1、为什么要使用dll
在文件相对较庞大时,webpack的构建速度是非常慢的,在通常的打包过程中,你所引用的诸如:jquery、bootstrap、react、react-router、redux、antd、vue、vue-router、vuex 等等众多库也会被打包进 bundle 文件中。由于这些库的内容基本不会发生改变,每次打包加入它们无疑是一种巨大的性能浪费,而dll则是在预先将第三方库提前打包。在开发时直接打包项目的业务代码,而不用重复打包第三方库,该方法主要使用webpack.DllPlugin进行。
2、相关配置文件
1、新建相关配置文件
在项目(vue项目)目录中的build文件夹下面新建webpack.dll.conf.js配置文件
2、package配置
在package.json中,在scripts配置项中新建键值对:
"build:dll": "webpack --config build/webpack.dll.conf.js"
对应执行的命令为 npm run build:dll,和npm run dev和npm run build类似
3、webpack.dll.conf.js配置说明
1、引入相关的模块
const path = require('path');
const webpack = require('webpack');
webpack为基础模块,在打包过程中会涉及到路径问题,故引入path模块
2、输入模块
entry: {
vendor: [
//提前打包一些基本不怎么修改的文件
'vue/dist/vue.esm.js',
'vue-router',
'vuex',
'axios',
'element-ui',
'element-ui/lib/locale/lang/zh-CN',
'echarts',
'mqtt',
'clipboard',
'babel-polyfill',
'vue-i18n',
'js-cookie'
]
},
配置为单个入口,传入值为数组,数组值为所有依赖的第三方库文件。
* webpack单入口语法(详情查看webpack文档(https://www.webpackjs.com/concepts/entry-points/)):当你向 entry 传入一个数组时会发生什么?向 entry 属性传入「文件路径(file path)数组」将创建“多个主入口(multi-main entry)”。在你想要多个依赖文件一起注入,并且将它们的依赖导向(graph)到一个“chunk”时,传入数组的方式就很有用。
3、输出模块
output: {
path: path.join(__dirname, '../static/dll'), //放在项目的static/js目录下面
filename: '[name].dll.js', //打包文件的名字
library: '[name]_library' //可选 暴露出的全局变量名
// vendor.dll.js中暴露出的全局变量名。
// 主要是给DllPlugin中的name使用,
// 故这里需要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},
这里主要输出两个东西,一个是vendor.dll.js(第三方库打包后的文件,需要在index.html中引用),一个是vendor-manifest.json(为第三方库的版本和相关库名称相关依赖文件,需要在build或者dev时排除第三库的依据),本配置会将上述两个文件打包,并放入static下面的dll文件夹中,方便使用。
4、插件
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '../static/dll', '[name]-manifest.json'), //生成上文说到清单文件,放在当前build文件下面,这个看你自己想放哪里了。
name: '[name]_library'
}),
//压缩 只是为了包更小一点
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: true,
drop_debugger: true
},
output: {
// 去掉注释内容
comments: false,
},
sourceMap: true
})
]
这里使用了两个插件,一个是webpack.DllPlugin用于打包dll,第二个为webpack.optimize.UglifyJsPlugin用于减小打包后的文件体积
5、解决element在dll打包后Tooltip组件不生效问题
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
}
},
原因未知
6、webapck.dll.conf.js完整代码
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: {
vendor: [
//提前打包一些基本不怎么修改的文件
'vue/dist/vue.esm.js',
'vue-router',
'vuex',
'axios',
'element-ui',
'element-ui/lib/locale/lang/zh-CN',
'echarts',
'mqtt',
'clipboard',
'babel-polyfill',
'vue-i18n',
'js-cookie'
]
},
output: {
path: path.join(__dirname, '../static/dll'), //放在项目的static/js目录下面
filename: '[name].dll.js', //打包文件的名字
library: '[name]_library' //可选 暴露出的全局变量名
// vendor.dll.js中暴露出的全局变量名。
// 主要是给DllPlugin中的name使用,
// 故这里需要和webpack.DllPlugin中的`name: '[name]_library',`保持一致。
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
}
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, '../static/dll', '[name]-manifest.json'), //生成上文说到清单文件,放在当前build文件下面,这个看你自己想放哪里了。
name: '[name]_library'
}),
//压缩 只是为了包更小一点
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: true,
drop_debugger: true
},
output: {
// 去掉注释内容
comments: false,
},
sourceMap: true
})
]
};
7、执行dll构建
npm run build:dll,这个命令和package.json配置有关,可以参考2.2修改,构建完成后在static下面会生产dll文件夹,包含vendor.dll.js和vendor-manifest.json,需将vendor.dll.js引入index.html中
4、webpack.dev.conf.js和webpack.prod.conf.js配置
如果在npm run build:dll后,立即执行npm run build会发现,打包后的文件体积并没有减小,原因在于执行npm run build的时候没有排除已经打包的第三方库。
这时需要在webpack.dev.conf.js和webpack.prod.conf.js中的plugins配置项中加入下面相关配置即可。
new webpack.DllReferencePlugin({
context: path.resolve(__dirname, '..'),
manifest: require('../static/dll/vendor-manifest.json')
}),