在前端項目中,咱們但願第三方庫(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,同時也增長了這些庫的緩存。