Webpack 打包太慢? 試試 Dllplugin

webpack在build包的時候,有時候會遇到打包時間很長的問題,這裏提供了一個解決方案,讓打包如絲般順滑~javascript

1. 介紹

在用 Webpack 打包的時候,對於一些不常常更新的第三方庫,好比 reactlodashvue 咱們但願能和本身的代碼分離開,Webpack 社區有兩種方案html

  • CommonsChunkPlugin
  • DLLPlugin

對於 CommonsChunkPlugin,webpack 每次打包實際仍是須要去處理這些第三方庫,只是打包完以後,能把第三方庫和咱們本身的代碼分開。而 DLLPlugin 則是能把第三方代碼徹底分離開,即每次只打包項目自身的代碼。Dll這個概念是借鑑了Windows系統的dll,一個dll包,就是一個純純的依賴庫,它自己不能運行,是用來給你的app引用的。前端

2. 模板webpack-simple 用法

要使用 DLLPlugin,須要額外新建一個配置文件。因此對於用這種方式打包的項目,通常會有下面兩個配置文件vue

  • webpack.config.js
  • webpack.dll.config.js

在項目根目錄新建一個文件 webpack.dll.config.jsjava

const path    = require('path');
const webpack = require('webpack');
module.exports = {
  entry: {
      vendor: ['vue-router','vuex','vue/dist/vue.common.js','vue/dist/vue.js','vue-loader/lib/component-normalizer.js','vue']
  },
  output: {
    path: path.resolve('./dist'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.resolve('./dist', '[name]-manifest.json'),
      name: '[name]_library'
    })
  ]
};
複製代碼

這是把用到的第三方插件添加到 vendor 中。 而後在webpack.config.js中添加代碼react

plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./dist/vendor-manifest.json')
    })
  ]
複製代碼

**再在入口html文件中引入 vendor.dll.js ** <script type="text/javascript" src="./../vendor.dll.js"></script>webpack

而後在package.json文件中添加快捷命令(build:dll)ios

"scripts": {
    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules",
    "build:dll": "webpack --config webpack.dll.config.js"
  },
複製代碼

最後打包的時候首先執行npm run build:dll命令會在打包目錄下生成 vendor-manifest.json 文件與 vendor.dll.js 文件。 打包dll的時候,Webpack會將全部包含的庫作一個索引,寫在一個manifest文件中,而引用dll的代碼(dll user)在打包的時候,只須要讀取這個manifest文件,就能夠了。git

再執行npm run build 發現如今的webpack打包速度爲2,3秒左右,與以前的20秒左右快了不少。github

3. 模板webpack 用法

在build下建立 webpack.dll.config.js

內容:

const path = require('path')
const webpack = require('webpack')
module.exports = {
  entry: {
    vendor: [
      'vue-router',
      'vuex',
      'vue/dist/vue.common.js',
      'vue/dist/vue.js',
      'vue-loader/lib/component-normalizer.js',
      'vue',
      'axios',
      'echarts'
    ]
  },
  output: {
    path: path.resolve('./dist'),
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.resolve('./dist', '[name]-manifest.json'),
      name: '[name]_library'
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}
複製代碼

建議加上代碼壓縮插件,不然dll包會比較大。

在 webpack.prod.conf.js 的 plugin 後面加入配置

new webpack.DllReferencePlugin({
    manifest: require('../dist/vendor-manifest.json')
})
複製代碼

根目錄下的入口 index.html 加入引用 <script type="text/javascript" src="./vendor.dll.js"></script>

package.json的script里加入快捷命令 "build:dll": "webpack --config build/webpack.dll.config.js"

要生成dll時運行npm run build:dll,即生成dist目錄下兩個文件 vender-manifest.jsonvender.dll.js。 而後正式生成 prod npm run build:prod,即生成除webpack.dll.config.js中指定包以外的其餘打包文件。

在嘗試在 vue-element-admin 中引入 DllPlugin 時,加入20個打包項,測試結果: 原來的打包時間:

引入 DllPlugin 後的打包時間:

能夠看到大幅縮短了打包時間~

4. 另外一種方法 externals 選項

也可使用 externals 讓webpack不打包某部分,而後在其餘地方引入cdn上的js文件,利用緩存下載cdn文件達到減小打包時間的目的。 配置externals選項

// webpack.prod.config.js
// 多餘代碼省略
module.exports = {
    externals: {
        'vue': 'window.Vue',
        'vuex': 'window.Vuex',
        'vue-router': 'window.VueRouter'
        ...
    }
}

// 配置externals以後,webpack不會把配置項中的代碼打包進去,別忘了須要在外部引入cdn上的js文件
// html
<body>
    <script src="XXX/cdn/vue.min.js"></script>
    ......
</body>
複製代碼

網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~

參考:

  1. Webpack DLL 用法
  2. 使用webpack.DllPlugin與webpack.DllReferencePlugin解決webpack打包慢問題
  3. webpack文檔
  4. Webpack的dll功能

PS:歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~

另外能夠加入「前端下午茶交流羣」微信羣,長按識別下面二維碼便可加我好友,備註加羣,我拉你入羣~