在前端项目中,咱们但愿第三方库(vendors
)和本身写的代码能够分开打包,vue-cli
也帮咱们配好了webpack
的CommonsChunkPlugin
,可是在使用vue-cli
的打包的过程当中有一些痛点。css
verdors
缓存失效改变了app.js的一点儿代码,verdors
打包的chunkhash
就会改变,致使每次发布,vendors
的缓存都会失效。这样增长了用户的流量消耗和首屏加载时间。html
在公司的台式机打包一次要花费30s,在我的笔记本上则须要花费40s之多。前端
为了解决上述问题,在网上查找资料后,找到使用 webpack dll
这个方案。vue
先贴上个人webpack.dll.conf.js
配置代码node
var path = require('path'); var webpack = require('webpack'); var config = require('../config') var ExtractTextPlugin = require('extract-text-webpack-plugin'); // 提取css var AssetsPlugin = require('assets-webpack-plugin'); // 生成文件名,配合HtmlWebpackPlugin增长打包后dll的缓存 module.exports = { entry: { libs: [ 'vue-infinite-scroll', 'vue-cookie', 'jquery', 'iscroll', 'weui.js', 'video.js', 'babel-polyfill', 'resetcss', 'font-awesome/css/font-awesome.min.css', 'video.js/dist/video-js.min.css', ] }, output: { path: path.resolve(__dirname, '../public'), filename: '[name].[chunkhash:7].js', library: '[name]_library' }, plugins: [ new webpack.DllPlugin({ path: path.resolve(__dirname, '../public/[name]-mainfest.json'), name: '[name]_library', context: __dirname // 执行的上下文环境,对以后DllReferencePlugin有用 }), new ExtractTextPlugin('[name].[contenthash:7].css'), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, }), new AssetsPlugin({ filename: 'bundle-config.json', path: './public' }), ], module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: "css-loader" }) }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', query: { limit: 10000, name: 'img/[name].[hash:7].[ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', query: { limit: 10000, name: 'fonts/[name].[hash:7].[ext]' } } ] }, }
entry
配置须要dll打包的库module
配置处理对应文件类型的loader三、增长 webpack.DllPlugin
插件jquery
mainfest.json
文件的绝对路径。mainfest.json
里面的内容为全部被打包到dll.js文件模块id的映射。name
:webpack
打包时mainfest.json包含的库的暴露出来的函数名名contenxt
(可选):引入manifest
文件的context
,默认为webpack
的context
在webpack.base.conf.js
的plugins
增长webpack
new webpack.DllReferencePlugin({ context: __dirname, manifest: require('../public/libs-mainfest.json') // 指向生成的manifest.json }),
注:上面提到经过AssetsPlugin
和HtmlWebpackPlugin
给打包的dll.js各dll.css增长缓存机制web
AssetsPlugin
生成的bundle-config.js
vue-cli
{"libs":{"js":"libs.f7d8ef0.js","css":"libs.e2245d7.css"}}
webpack.dev.conf.js
文件增长如下代码json
var bundleConfig = require("../public/bundle-config.json") new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true, libJsName:bundleConfig.libs.js, libCssName:bundleConfig.libs.css, env:config.dev.env, }),
在index.html
引入生成的dll.js,dll.css
<link rel="stylesheet" href="./public/<%= htmlWebpackPlugin.options.libCssName %>"> <script src="./public/<%= htmlWebpackPlugin.options.libJsName %>"></script>
上面为开发环境的配置,生产环境对应修改就能够了。
build.dll.js
文件,var path = require('path'); var utils = require('./utils') var webpack = require('webpack'); var config = require('../config') var utils = require('./utils') var dllConfig = require('./webpack.dll.conf'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var AssetsPlugin = require('assets-webpack-plugin'); var chalk = require('chalk') var rm = require('rimraf') var ora = require('ora') var spinner = ora({ color: 'green', text: '正为生产环境打包dll包,耐心点,否则自动关机。。。' }) spinner.start() rm(path.resolve(__dirname, '../public'), err => { if (err) throw err webpack(dllConfig,function (err, stats) { spinner.stop() if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n\n') console.log(chalk.cyan(' dll打包完成.\n')) }) });
package.json
script
中加上"build:dll": "node build/buildDll.js"
注:开发和生产环境都要首先使用 webpack运行
webpack.dll.conf.js
生成dll.js, dll.css, mainfest.json
文件,每次改变库文件也都须要从新执行一遍。
优化前笔记本上打包时间为4000ms,优化后笔记本打包时间为1800ms,同时也增长了这些库的缓存。