这段时间在对公司的打包构建速度和app.js文件大小进行优化。使用到了webpack的DllPlugin和DllReferencePlugin。今天就来简单讲讲它们的使用。javascript
其实对于这两个插件网上已经有不少各类各样的文章了。不过笔者认为,那些文章都写得很棒,可是对于部分须要注意的地方都没有说明。这里笔者就根据本身的理解讲讲我的的理解。若是有什么不对的地方但愿能有人指出,小弟在此先谢过了。html
首先咱们来说讲DLLPlugin这个插件吧。这个插件的做用是建立dll文件和manifest文件。dll文件就是就是咱们须要引入的文件,manifest文件是引导webpack引入到当前项目的文件。好吧,直接贴代码:vue
webpack.dll.conf.jsjava
var path = require('path') var webpack = require('webpack') var CleanWebpackPlugin = require('clean-webpack-plugin') var config = require('../config') var __root = xxx // 这里是你的根路径 // 这里是静态资源路径,若是使用vue-cli的,就是根目录下的static目录; // 若是使用@vue/cli的就是根目录下的public目录。使用其余的脚手架须要根据具体状况考虑。 var static = xxx module.exports = { context: __root, // 这里配置的context就是后面dll的context entry: { 'core': ['vue', 'vue-router', 'vuex'], 'asset': ['axios', 'fastclick'] }, output: { path: path.resolve(static, 'lib'), filename: '[name]-[chunkhash:7].dll.js', library: 'lib_[name]', // *** 这里不要添加libraryTarget,不然webpack打包时会出错。 // (提示是__WEBPACK__EXTERNAL__MODULE__xxx未定义) *** // libraryTarget: 'umd' }, resolve: { modules: [path.resolve(__root, 'node_modules')], extensions: ['.js', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js' } }, // 这里没有写loaders,若是有须要能够自行添加loaders plugins: [ // *** 这里很关键 *** new webpack.DllPlugin({ // 由于上面写了context,因此这里能够不指定context // 这里manifest的名字必需要有变量,由于相似上面的core和asset会分别建立一个manifest, // 若是名称相同,manifest会生成不规范的json,在引用时会报错。 path: path.resolve(__root, 'static/manifest/[name].manifest.json'), name: 'lib_[name]' // *** 这里的名字必须与output.library一致 *** }), // 这个是用来稳定hash值,防止出现webpack的hash出现莫名的变化 new webpack.HashedModuleIdsPlugin(), new webpack.NamedChunksPlugin() ... 其余插件 ] }
上面就是webpack.dll.conf.js的主要配置。执行以后会在static文件夹(在vue-cli生成的项目中用于存放不须要webpack构建的静态文件【@vue/cli中的目录名为Public】)下生成两个文件夹(lib文件夹和mainfest文件夹)。其中lib下的文件为咱们已经打包好的组件库,mainfest下的文件在引入项目时有用(是一个JSON文件)。node
webpack.conf.jswebpack
var path = require('path') // 获取dll文件的manifest function getDllManifest () { var plugins = [] Object.keys({ 'core': ['vue', 'vue-router', 'vuex'], 'asset': ['axios', 'fastclick'] }).forEach((name) => { plugins.push( new webpack.DllReferencePlugin({ context: __root, // 这里的context必须与DllPlugin中的context保持一致 manifest: path.resolve(__root, 'static/manifest/[name].manifest.json').replace(/\[name\]/gi, name) }) ) }) return plugins } module.exports = { entry: { app: './src/main.js' }, output: { path: path.resolve(__dirname, '..') filename: 'js/[name]js' }, ... 其余代码 plugins: [ // *** 因此这里可能会引入多个DllReferencePlugin,具体要看有几个manifest文件了。*** ...getDllManifest(), new HtmlWebpackPlugin({ filename: utils.assetsPath('page/retail.html'), template: path.join(config.dev.page, 'retail.html'), inject: true, minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // dll文件须要插件将其引入到html文件中,以方便后续使用 new HTMLWebpackIncludeAssetsPlugin({ append: false, publicPath: config.build.assetsPublicPath, assets: [{ path: config.build.assetsSubDirectory, glob: '**/*.js', globPath: config.dll.static }], }), // 将dll文件拷贝到你的dist目录下 new CopyWebpackPlugin([ { // 这里是dll文件当前所在的文件目录 from: static, // 这里是生产环境的资源地址 to: config.build.assetsSubDirectory, // 过滤static中的部分文件 ignore: ['.*', 'manifest/*'] } ]) ] }
getDllManifest方法是将打包好的库引入到项目中(就是在html中生成script标签的方式引入,它会在app.js以前生成,保证代码执行顺序的正确性),并保证构建工具不会再次对它进行打包。以上就是生成和引用dll文件的配置。ios
注:git
output.library
必须与DllPlugin
配置中的name
字段保持统一。libraryTarget
,不然在运行时会报__WEBPACK__EXTERNAL__MODULE__xxx is not defined
错误。DllPlugin
的context
和DllReferencePlugin
的context
要保持一致。manifest
的名字最好是可配置的,这样方便生成多个dll文件。讲webpack构建优化的github