Webpack的dll功能使⽤
最近使⽤Webpack遇到了⼀个坑。
我们构建前端项⽬的时候,往往希望第三⽅库(vendors)和⾃⼰写的代码可以分开打包,因为第三⽅库往往不需要经常打包更新。对此Webpack的建议
⽤CommonsChunkPlugin来单独打包第三⽅库。
entry: {
vendor: ["jquery", "other-lib"],
app: "./entry"
}
new CommonsChunkPlugin({
name: "vendor",
// filename: "vendor.js"
// (Give the chunk a different name)
minChunks: Infinity,
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
})
通常为了对抗缓存,我们会给售出⽂件的⽂件名中加⼊hash的后缀——但是——我们编辑了app部分的代码后,重新打包,发现vendor的hash也变化了!
这么⼀来,意味着每次发布版本的时候,vendor代码都要刷新,即使我并没有修改其中的代码。这样并不符合我们分开打包的初衷。
带着问题我浏览了Github上的,发现了⼀个神器:dll。
Dll是Webpack最近新加的功能,我在⽹上并没有到什么中⽂的介绍,所以在这⾥我就简单介绍⼀下。
Dll这个概念应该是借鉴了Windows系统的dll。⼀个dll包,就是⼀个纯纯的依赖库,它本⾝不能运⾏,是⽤来给你的app引⽤的。
打包dll的时候,Webpack会将所有包含的库做⼀个索引,写在⼀个manifest⽂件中,⽽引⽤dll的代码(dll user)在打包的时候,只需要读取这个manifest⽂件,就可以了。这么⼀来有⼏个好处:
1. Dll打包以后是独⽴存在的,只要其包含的库没有增减、升级,hash也不会变化,因此线上的dll代码不需要随着版本发布频繁更新。
2. App部分代码修改后,只需要编译app部分的代码,dll部分,只要包含的库没有增减、升级,就不需要重新打包。这样也⼤⼤提⾼了每次编译的速度。
3. 假设你有多个项⽬,使⽤了相同的⼀些依赖库,它们就可以共⽤⼀个dll。
如何使⽤呢?
⾸先要先建⽴⼀个dll的配置⽂件,entry只包含第三⽅库:
const webpack = require('webpack');
const vendors = [
'antd',
'isomorphic-fetch',
'react',
'react-dom',
'react-redux',
'react-router',
'redux',
'redux-promise-middleware',
'redux-thunk',
'superagent',
];
output: {
path: 'build',
filename: '[name].[chunkhash].js',
library: '[name]_[chunkhash]',
},
entry: {
vendor: vendors,
},
plugins: [
new webpack.DllPlugin({
path: 'manifest.json',
name: '[name]_[chunkhash]',
context: __dirname,
}),
],
react router dom 6};
webpack.DllPlugin的选项中,path是manifest⽂件的输出路径;name是dll暴露的对象名,要跟output.library保持⼀致;context是解析包路径的上下⽂,这个要跟接下来配置的dll user ⼀致。
运⾏Webpack,会输出两个⽂件⼀个是打包好的vendor.js,⼀个就是manifest.json,长这样:
{
"name": "vendor_ac51ba426d4f259b8b18",
"content": {
"./node_modules/antd/dist/antd.js": 1,
"./node_modules/react/react.js": 2,
"./node_modules/react/lib/React.js": 3,
"./node_modules/react/node_modules/object-assign/index.js": 4,
"./node_modules/react/lib/ReactChildren.js": 5,
"./node_modules/react/lib/PooledClass.js": 6,
"./node_modules/react/lib/reactProdInvariant.js": 7,
"./node_modules/fbjs/lib/invariant.js": 8,
"./node_modules/react/lib/ReactElement.js": 9,
............
Webpack将每个库都进⾏了编号索引,之后的dll user可以读取这个⽂件,直接⽤id来引⽤。
Dll user的配置:
const webpack = require('webpack');
output: {
path: 'build',
filename: '[name].[chunkhash].js',
},
entry: {
app: './src/index.js',
},
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./manifest.json'),
}),
],
};
DllReferencePlugin的选项中,context需要跟之前保持⼀致,这个⽤来指导Webpack匹配manifest中库的路径;manifest⽤来引⼊刚才输出的manifest⽂件。运⾏Webpack之后,结果如下:
对⽐⼀下不做分离的情况下打包的结果:
速度快了,⽂件也⼩了。
平时开发的时候,修改代码后重新编译的速度会⼤⼤减少,节省时间。
如果有多个项⽬,使⽤相同的⼀套库,你可以在打包的时候引⽤相同的manifest⽂件,这样就可以在项⽬之间共享了。
参考:
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。