此文已由作者刘诗川授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
上面介绍的打包出的带有hash的js文件,如果手动去引入,那就太繁琐了,所以需要借助HtmlWebpackPlugin
来自动注入打包出的脚本,常用配置如下:
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',//生成的html的文件名,可以带有子目录信息,默认就是index.html
template: 'index.html',//生成的html所参照的模板文件的位置,模板中可以准写入一些需要预置的信息,比如要为Vue或者React准备的mount的节点,就需要先在模板中写入
inject: true,//为true时,会自动把css文件写入head中(如果有用ExtractTextPlugin提取的话),把js文件写入到body最后
chunksSortMode: 'dependency',//设置为dependency可以才能使得上面提到的CommonsChunkPlugin生成的3个js文件按照依赖的顺序依次写入html中
})
]
最后介绍一下webpack支持的异步按需加载模块机制。我们提供给用户的网页,如果想要在用户触发某些操作的时候,才去通过网络加载所需的模块,这样既可以加快用户首次页面加载的速度,也可以节省用户的流量。 webpack是同时支持CommonJs
和AMD
模块化规范的,所以,有两种异步加载模块的写法:
function btnClickHandler(){
/**
* CommonJs异步加载方案
*/
require.ensure([], () => {
var utils = require('./js/utils').default;
self.msg = utils;
});
/**
* AMD 异步加载方案
*/
require(['./js/utils'], utils => {
self.msg = utils.default;
})
}
比如放在一个按钮的点击事件的处理函数中,只有当用户点击该按钮,才会去下载这个./js/utils
模块。而webpack在打包成,会自动识别这种写法的代码,把它们识别为需要按需异步加载的模块,单独进行打包,这种按需加载的文件,就是通过上文中webpack配置中output.chunkFilename
来指定文件名的格式。 当然,也可以通过require.ensure()
方法的第三个参数来指定这个chunk的名称,在output.chunkFilename
中就可以使用'[name].[chunkhash:7].js'
来指定这些异步模块包的文件名了。 异步加载文件的过程展示如下:
webpack2在前段时间发布了,相对于1.X版本有了一些改变和优化,这里简单介绍一些常用的吧。
这三项被合并成了一个配置项:resolve.modules
,我之前就觉得那三项的配置有点混乱,webpack2也为此做了精简:
resolve: {
modules: [
path.join(__dirname, "src"),
"node_modules"
]
}
这三项也被精简合并成了一项:modules.rules
,而且不再允许省略-loader
扩展名(除非特意去配置),loader
的参数配置只能写在 rule.options
内部不能写在外面:
module: {
rules: [{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true
}
}
]
}]
}
ExtractTextWebpackPlugin 1.x版本在webpack2中将无法使用,适配webpack2的ExtractTextWebpackPlugin配置方式有所变化:
module: {
rules: [
test: /.css$/,
loader: ExtractTextPlugin.extract({
fallbackLoader: "style-loader",
loader: "css-loader",
publicPath: "/dist"
})
]
},
plugins: [
new ExtractTextPlugin({
filename: "bundle.css",
disable: false,
allChunks: true
})
]
webpack2现在支持ES2015的import()
模块异步加载语法,而且它会返回一个Promise
对象,这样模块异步加载出错也能有方法捕捉了:
function btnClickHandler() {
import('./js/utils').then(module => {
return module.default;
}).catch(err => {
console.log("Chunk loading failed");
});
}
import()
加载机制还支持表达式写法:
function route(path, query) {
return import(`./routes/${path}/route`)
.then(route => new route.Route(query));
}
webpack2将会把所有可能符合表达式的模块都另外打包起来。 要使用webpack2的这个特性,需要加一个配置项,使的Babel
不会将这些代码转化为ES3的代码。
{
"presets": [
["es2015", { "modules": false }]
]
}
但是import()
不具备上文所提到的require.ensure()
方法的第三个参数可以指定chunkname
的功能,如果需要用到这个功能,还是可以得使用require.ensure()
就像上面一点中使用到的,webpack2现在支持ES2015中的模板字符串语法了。
function route(path, query) {
return import(`./routes/${path}/route`)
.then(route => new route.Route(query));
}
webpack1的配置文件只能是一个配置对象,webpack2支持从配置文件中返回一个Promise
对象,这就是使得我们可以更直观的在一个文件中支持多种环境的配置,而不需要像有的项目那样通过不同的配置文件来管理。
module.exports = function() {
// 异步读取语言包
return fetchLangs().then(lang => ({
entry: "...",
// ...
plugins: [
new DefinePlugin({ LANGUAGE: lang })
]
}));
};
以上就是我使用webpack的一点学习经验,并不全面,不对之处请帮忙指出,谢谢。
相关文章:webpack常用配置详解上篇
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。