首先说说,为什么要使用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'))
}),
]