DllPlugin 插件配置实践node
DLLPlugin 和 DLLReferencePlugin 用某种方法实现了拆分 bundles,同时还大大提高了构建的速度。jquery
工程目录webpack
### 目录结构以下:
dll-plugin # 工程名
| |--- dist # 打包后生成的目录文件
| |--- node_modules # 全部的依赖包
| |--- src # 存放全部js文件
| | |-- pageOne.js
| | |-- pageTwo.js # js入口文件
| |--- webpack.config.js # webpack配置文件
| |--- webpack.dll.config.js # 打包第三方依赖的库文件
| |--- README.md
| |--- package.json
复制代码
首先咱们须要在项目下建立一个单独的打包dll文件的配置文件webpack.dll.config.jsweb
const path = require('path');
const webpack = require('webpack');
const library = '[name]_dll_lib';
module.exports = {
mode: 'development',
// 入口, 接收多个参数做为多个入口
entry: {
// dll文件中包含的第三方库列表
jquery: ['jquery'],
echarts: ['echarts']
},
output: {
// 文件名称
filename: 'dll/[name].dll.js',
// 文件输出目录
path: path.resolve(__dirname, 'dist'),
// 存放dll文件的全局变量名称,须要注意命名冲突
library: library
},
plugins: [
new webpack.DllPlugin({
// manifest文件中的name属性值, 需与output.library保持一致
name: library,
// mainfest文件输出路径和文件名称
path: path.join(__dirname, 'dist', 'dll/[name].manifest.json')
})
]
}
复制代码
接下来须要在webpack.config中使用的manifestnpm
module.exports = {
/***** other options ******/
plugins: [
// 告诉webpack使用了哪些第三方库代码
new DllReferencePlugin({
// manifest文件中请求的上下文,
context: __dirname,
// jquery 映射到json文件上去
manifest: require('./dist/jquery.manifest.json')
}),
new DllReferencePlugin({
// echarts 映射到json文件上去
manifest: require('./dist/echarts.manifest.json')
})
]
}
复制代码
package.json 中添加打包命令json
"scripts": {
"build:dll": "webpack --config webpack.dll.config.js",
},
复制代码
运行npm run build:dll, 运行完成以后,会在dist/dll目录下生成 echarts.dll.js, echarts.manifest.json,jquery.dll.js, jquery.manifest.json 文件echarts
在src/pageOne.js入口文件中引入jquery和echarts库, src/pageTwo.js文件中不引入任何依赖ide
const jquery = require('jquery');
const echarts = require('echarts');
console.log("Hello World from pageOne main file!");
复制代码
执行打包命令 npm run build 函数
发现打包的时间是668ms, pageOne和pageTwo打包出来的大小仅相差了3kb, 显然第三方库代码没有打包到项目文件里。再来对比一下使用dll和不使用dll的状况优化
打包时间变成了1781ms, 增长了近两倍, 打包大小变为3683KB, 将jquery和echarts第三方库代码打包进了pageOne中。
使用DllPlugin分离bundle,构建速度和工程文件大小优化明显。
了解dll-plugin的做用和用法后,再来看看它是怎么实现的。
先看一下打包生成的dll文件, echarts.dll.js:
var echarts_dll_lib = (function(modules) {
// ... 此处省略 webpackBootstrap 函数代码
}({
"./node_modules/echarts/index.js": (function(module, exports, __webpack_require__) {
// ID为./node_modules/echarts/index.js模块对应的代码
}),
"./node_modules/echarts/lib/CoordinateSystem.js": (function(module, exports, __webpack_require__) {
// ID为./node_modules/echarts/lib/CoordinateSystem.js模块对应的代码
}),
// ......
}));
复制代码
DllPlugin 将echarts依赖导出成了一个函数,并将echarts_dll_lib挂载到window全局对象中, 能够看到dll为echarts中的各个模块都分配了一个Id。
再看echarts.manifest.json:
{
"name":"echarts_dll_lib",
"content": {
"./node_modules/echarts/lib/util/animation.js": {
"id": "./node_modules/echarts/lib/util/animation.js",
"buildMeta":{"providedExports":true}
},
// .....
"./node_modules/echarts/index.js": {
"id":"./node_modules/echarts/index.js",
"buildMeta": {"providedExports":true}
},
// ......
}
}
复制代码
echarts.manifest.json 文件能够清楚的看到与其对应的dll.js文件中包含了哪些模块,以及每一个模块的路径和ID。
在webpackConfig中配置DllReferencePlugin引入manifest, 当项目中引入echarts模块时,会经过路径匹配到manifest中的对应模块id, 再经过模块id和name属性, 找到挂载再window上的对应的模块代码。