基本原理
手动分包的总体思路是:
- 先单独的打包公共模块
单独打包公共模块
公共模块会被打包成为动态链接库(dll Dynamic Link Library),并生成资源清单
- 根据入口模块进行正常打包
打包时,如果发现模块中使用了资源清单中描述的模块,则不会形成下面的代码结构:
//源码,入口文件index.js
import $ from "jquery"
import _ from "lodash"
_.isArray($(".red"));
由于资源清单中包含jquery和lodash两个模块,因此打包结果的大致格式是:
(function(modules){
//...
})({
// index.js文件的打包结果并没有变化
"./src/index.js":
function(module, exports, __webpack_require__){
var $ = __webpack_require__("./node_modules/jquery/index.js")
var _ = __webpack_require__("./node_modules/lodash/index.js")
_.isArray($(".red"));
},
// 由于资源清单中存在,jquery的代码并不会出现在这里
"./node_modules/jquery/index.js":
function(module, exports, __webpack_require__){
module.exports = jquery;
},
// 由于资源清单中存在,lodash的代码并不会出现在这里
"./node_modules/lodash/index.js":
function(module, exports, __webpack_require__){
module.exports = lodash;
}
})
打包公共模块
打包公共模块是一个独立的打包过程
首先在package.json中:
"scripts": {
"dev": "webpack",
"dll": "webpack --config webpack.dll.config.js"
},
单独打包公共模块,暴露变量名
// webpack.dll.config.js
module.exports = {
mode: "production",
entry: {
jquery: ["jquery"], //必须是数组
lodash: ["lodash"]
},
output: {
filename: "dll/[name].js",
library: "[name]" //每个bundle暴露的全局变量名
//或者libraryTarget:"var" 全局形式来暴露
}
};
利用DllPlugin生成资源清单
// webpack.dll.config.js
module.exports = {
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, "dll", "[name].manifest.json"), //资源清单的保存位置
name: "[name]"//资源清单中,暴露的变量名
})
]
};
使用公共模块
在页面中手动引入公共模块
<script src="./dll/jquery.js"></script>
<script src="./dll/lodash.js"></script>
重新设置clean-webpack-plugin
如果使用了插件clean-webpack-plugin,为了避免它把公共模块清除,需要做出以下配置
new CleanWebpackPlugin({
// 要清除的文件或目录
// 排除掉dll目录本身和它里面的文件
cleanOnceBeforeBuildPatterns: ["**/*", '!dll', '!dll/*']
})
目录和文件的匹配规则使用的是globbing patterns
- 使用DllReferencePlugin控制打包结果
webpack.config:
module.exports = {
plugins:[
new webpack.DllReferencePlugin({
manifest: require("./dll/jquery.manifest.json")
}),
new webpack.DllReferencePlugin({
manifest: require("./dll/lodash.manifest.json")
})
]
}
总结
手动打包的过程:
- 开启output.library暴露公共模块
- 用DllPlugin创建资源清单
- 用DllReferencePlugin使用资源清单
手动打包的注意事项:
- 资源清单不参与运行,可以不放到打包目录中
- 记得手动引入公共JS,以及避免被删除
- 不要对小型的公共JS库使用
优点:
- 极大提升自身模块的打包速度
- 极大的缩小了自身文件体积
- 有利于浏览器缓存第三方库的公共代码
缺点:
- 使用非常繁琐
- 如果第三方库中包含重复代码,则效果不太理想