基於vue-cli的webpack配置優化

基於vue-cli優化的webpack配置

大概分爲如下幾點javascript

  • 經過 externals 配置來提取經常使用庫,引用外鏈
  • 配置CommonsChunkPlugin提取公用代碼 (vue-cli已作)
  • 善用aliasvue-cli配置了一部分)
  • 啓用DllPluginDllReferencePlugin預編譯庫文件
  • happypack開啓多核構建項目
  • webpack-parallel-uglify-plugin來替換webpack自己的UglifyJS來進行代碼壓縮混淆
  • 升級webpack至3.x版本開啓Scope Hoisting

externals

文檔地址 https://doc.webpack-china.org...css

防止將某些 import 的包(package)打包到 bundle 中,而是在運行時(runtime)再去從外部獲取這些擴展依賴(external dependencies)。html

CommonsChunkPlugin

文檔地址 https://doc.webpack-china.org...vue

CommonsChunkPlugin 插件,是一個可選的用於創建一個獨立文件(又稱做 chunk)的功能,這個文件包括多個入口 chunk 的公共模塊。經過將公共模塊拆出來,最終合成的文件可以在最開始的時候加載一次,便存起來到緩存中供後續使用。這個帶來速度上的提高,由於瀏覽器會迅速將公共的代碼從緩存中取出來,而不是每次訪問一個新頁面時,再去加載一個更大的文件。java

resolve.alias

文檔地址 https://doc.webpack-china.org...node

建立 import 或 require 的別名,來確保模塊引入變得更簡單。例如,一些位於 src/ 文件夾下的經常使用模塊:webpack

DllPlugin和DllReferencePlugin

文檔地址 https://doc.webpack-china.org...git

Dll打包之後是獨立存在的,只要其包含的庫沒有增減、升級,hash也不會變化,所以線上的dll代碼不須要隨着版本發佈頻繁更新。使用Dll打包的基本上都是獨立庫文件,這類文件有一個特性就是變化不大。,只要包含的庫沒有升級, 增減,就不須要從新打包。這樣也提升了構建速度。es6

通常是用於打包階段github

  1. build文件夾下新建webpack.dll.conf.js文件
var path = require('path');
var webpack = require('webpack');
var AssetsPlugin = require('assets-webpack-plugin');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var config = require('../config');
var env = config.build.env;

module.exports = {
  entry: {
    libs: [
      'babel-polyfill',
      'vue/dist/vue.esm.js',
      'vue-router',
      'vuex',
      'element-ui',
      'echarts',
      'mockjs',
    ],
  },
  output: {
    path: path.resolve(__dirname, '../libs'),
    filename: '[name].[chunkhash:7].js',
    library: '[name]_library',
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': env,
    }),
    new webpack.DllPlugin({
      path: path.resolve(__dirname, '../libs/[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: './libs',
    }),
    new CleanWebpackPlugin(['libs'], {
      root: path.join(__dirname, '../'), // 絕對路徑
      verbose: true,
      dry: false,
    }),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
      },
    ],
  },
};
  1. build文件夾下新建build-dll.js文件
var path = require("path");
var webpack = require("webpack");
var dllConfig = require("./webpack.dll.conf");
var chalk = require("chalk");
var rm = require("rimraf");
var ora = require("ora");

var spinner = ora({
  color: "green",
  text: "building for Dll..."
});
spinner.start();
rm(path.resolve(__dirname, "../libs"), 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(" build dll succeed !.\n"));
  });
});
  1. 修改webpack.prod.conf.js文件
var bundleConfig = require("../libs/bundle-config.json");
...
...
plugins: [
  // 增長DllReferencePlugin配置
  new webpack.DllReferencePlugin({
    context: __dirname,
    manifest: require("../libs/libs-mainfest.json") // 指向生成的manifest.json
  }),
  ...
  ...
  new HtmlWebpackPlugin({
    ...
    // 增長兩個變量
    libJsName: bundleConfig.libs.js,
    libCssName: bundleConfig.libs.css,
  }),
  ...
  ...
  // 增長一個靜態文件目錄
   new CopyWebpackPlugin([
     ...
     ...
    {
      from: path.resolve(__dirname, "../libs"),
      to: config.build.assetsSubDirectory,
      ignore: ["*.json"]
    }
  ])
]
  1. 修改模版文件index.html
<body>
  <div id="app"></div>
  <!-- built files will be auto injected -->
  <% if (htmlWebpackPlugin.options.libCssName){ %>
    <link rel="stylesheet" href="./static/<%= htmlWebpackPlugin.options.libCssName %>">
  <% } %>

  <% if (htmlWebpackPlugin.options.libJsName){ %>
      <script src="./static/<%= htmlWebpackPlugin.options.libJsName %>"></script>
  <% } %>
</body>
  1. 修改package.json,增長scripts
"scripts": {
  // 增長
  "dll": "node build/build-dll.js"
},
  1. npm run dll先執行預編譯,而後在打包項目文件,若是引入的類庫文件沒有變動就再也不須要再次執行預編譯

happypack

文檔地址 https://github.com/amireh/hap...

通常node.js是單線程執行編譯,而happypack則是啓動node的多線程進行構建,大大提升了構建速度。

在插件中new一個新的happypack進程出來,而後再使用使用loader的地方替換成對應的id

  1. 修改webpack.base.conf.js文件
var HappyPack = require('happypack');
var os = require('os');
var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
...
...
// 增長plugins
 plugins: [
  new HappyPack({
    id: 'happy-babel-js',
    loaders: ['babel-loader?cacheDirectory=true'],
    threadPool: happyThreadPool,
  })
]
...
...
// 修改對應loader
{
  test: /\.js$/,
  loader: 'happypack/loader?id=happy-babel-js',
  include: [resolve('src'), resolve('test')],
}

webpack-parallel-uglify-plugin

文檔地址 https://github.com/gdborton/w...

webpack提供的UglifyJS插件因爲採用單線程壓縮,速度很慢 ,
webpack-parallel-uglify-plugin插件能夠並行運行UglifyJS插件,這能夠有效減小構建時間。

  1. 修改webpack.prod.conf.js文件
var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
...
...
// 刪掉webpack提供的UglifyJS插件
// new webpack.optimize.UglifyJsPlugin({
//   compress: {
//     warnings: false,
//     drop_console: true
//   },
//   sourceMap: true
// }),
// 增長 webpack-parallel-uglify-plugin來替換
new ParallelUglifyPlugin({
  cacheDir: '.cache/',
  uglifyJS:{
    output: {
      comments: false
    },
    compress: {
      warnings: false
    }
  }
}),

webpack 3

webpack3新特性一覽 https://juejin.im/entry/59714...

webpack 3.x 提供了一個新的功能:Scope Hoisting,又譯做「做用域提高」。只需在配置文件中添加一個新的插件,就可讓 Webpack 打包出來的代碼文件更小、運行的更快。

  1. 修改webpack.prod.conf.js
...
...
plugins: [
  // 往plugins添加一個配置
  // ps 只針對es6的模塊化有效
  new webpack.optimize.ModuleConcatenationPlugin(),
]

ps:配置文件詳情請點擊 https://github.com/liaoyinglo...

相關文章
相關標籤/搜索