首先说说,为什么要使用dllplugin?
在项目开发中,我们会遇到很多的依赖,体积不小,而且他们都是公共模块,基本上不会有变动,所以考虑是不是可以把这部分公共的模块抽取出来,作为静态的资源,不需要每次都打包这块
虽然有CommonsChunkPlugin插件可以抽取公共模块,但是有如下缺点
- 每次打包都会重新构建公共模块
- 只要其中的模块有微小的变动,打包出来的公共文件就不一样,简单说,换台机器,同样是vendor.js,但是文件的内容是不一样的,每次发布,会增加cdn服务器的压力
于是dllplugin横空出世,它可以抽取你想要分离的公共模块生成一个js文件,然后在以后的开发和打包的过程中,都可以直接用预先编译好的js文件,也就是说,公共的依赖,不会每次都打包
使用如下
在创建文件config/webpack.config.dll,内容如下
const path = require('path')
const webpack = require('webpack')
const paths = require('./paths')
const getClientEnvironment = require('./env')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const publicPath = paths.servedPath
const publicUrl = publicPath.slice(0, -1)
const env = getClientEnvironment(publicUrl)
module.exports = {
entry: {
vendor: [
'antd'
]
},
output: {
path: paths.appPublic,
filename: 'static/js/[name].js',
library: '[name]_library', // same with webpack.DllPlugin name option
publicPath: publicPath
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(paths.appPublic, 'static/js/[name]-manifest.json'),
name: '[name]_library',
context: paths.appPublic
}),
]
}
添加下面内容到webpack的plugins中
new webpack.DllReferencePlugin({
context: paths.appPublic,
manifest: require(path.resolve(paths.appPublic, 'static/js/vendor-manifest.json'))
}),
接下来就可以愉快的玩耍了,在开发和打包的过程中,在遇到antd组件的时候,都不会从nodemodule中取,而是直接从vendor.js里面取,构建速度从20s降低到11秒,提升不小,还可以配置其他,进一步提升
但是这样有一个问题,那就是打包出来的完整的antd文件很大,超过2M,所以继续优化,在dll中按需引入antd组件,然后再拆分react相关公共模块,完整如下
const path = require('path')
const webpack = require('webpack')
const paths = require('./paths')
const getClientEnvironment = require('./env')
const publicPath = paths.servedPath
const publicUrl = publicPath.slice(0, -1)
const env = getClientEnvironment(publicUrl)
module.exports = {
entry: {
vendor: [
'antd/lib/form',
'antd/lib/steps',
'antd/lib/input',
'antd/lib/row',
'antd/lib/col',
'antd/lib/button',
'antd/lib/message',
'antd/lib/icon',
'antd/lib/cascader',
'antd/lib/checkbox',
'antd/lib/modal',
'antd/lib/upload',
'antd/lib/progress',
],
cm1: [
'react',
'react-router-dom',
'axios',
'mobx',
'mobx-react',
]
},
output: {
path: paths.appPublic,
filename: 'static/js/[name].shop.js',
library: '[name]_library', // same with webpack.DllPlugin name option
publicPath: publicPath
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(paths.appPublic, 'static/js/[name]-manifest.json'),
name: '[name]_library',
context: paths.appPublic
}),
]
}
webpack配置文件中plugin配置为
plugins: [
new webpack.DllReferencePlugin({
context: paths.appPublic,
manifest: require(path.resolve(paths.appPublic, 'static/js/vendor-manifest.json'))
}),
new webpack.DllReferencePlugin({
context: paths.appPublic,
manifest: require(path.resolve(paths.appPublic, 'static/js/cm1-manifest.json'))
}),
]