webpack實戰項目中代碼打包和優化總結

網上關於webpack的優化的已經很多了,只是都比較零散,結合實戰項目自己做個總結

webpack 優化,實際項目中主要做到了一下幾點:

1、 文件壓縮(css, js, html, 字體文件, 圖片文件)
2、 babel-loader 避免不必要的轉義
3、 babel-轉義結果進行緩存
4、 公共模塊的提取
5、 loader 轉爲多進程
6、 按需加載
7、 DllPlugin 增加開發時打包速度
8、 Gzip進行文件壓縮,webpack壓縮文件,後臺可以再次進行壓縮

接下來針對每一個細節點進行詳細說明

1、文件壓縮(html, css, js, 字體文件,圖片文件的壓縮和轉碼)

HtmlWebpackPlugin 官網鏈接 https://webpack.docschina.org/plugins/html-webpack-plugin/#src/components/Sidebar/Sidebar.jsx

關於 HtmlWebpackPlugin 的插件使用就不過多贅述,參考官方文檔,主要是用來壓縮代碼以及自動將打包後生成的就是文件插入到html中

如圖中所示的<script></script>標籤對js的引入都是該插件的功勞,具體用法和配置如下

plugins: [
 new HtmlWebpackPlugin({
  filename: config.build.index, // 指定項目的生成名稱
  template: 'index.html', // 將模板指向根那個目錄
  inject: true, // 指定生成的<script></script>放在那個目錄
  // 去掉空格、註釋、多餘的應用等等都在這裏配置
  minify: {
    removeComments: true,
    collapseWhitespace: true,
    removeAttributeQuotes: true
  },
  chunksSortMode: 'dependency', // 成產環境下的第三方依賴進行壓縮
 }),
]

js 壓縮用法同上,就不細講了參見官方文檔
https://webpack.docschina.org/guides/migrating/#uglifyjsplugin-sourcemap
css、圖片、字體文件壓縮主要通過 loader 來進行

配置如下:

 const webpackConfig = {
    module: {
      rules: [
        {
          loader: 'css-loader',
          options: {
            sourceMap: options.sourceMap
          }
        }
        {
          test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000, // 限制壓縮文件的大小
            name: utils.assetsPath('media/[name].[hash:7].[ext]') // 文件的路徑
          }
        },
        {
          test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
          loader: 'url-loader',
          options: {
            limit: 10000,
            name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
          }
        }
      ]
    }
  }


2、3 關於babel 的轉碼和轉碼緩存

const webpackConfig = {
 module: {
  rules: [
   {
      test: /\.js$/,
      loader: 'babel-loader?cacheDirectory=true', // 將轉譯結果緩存至文件系統
      include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]  // 針對特定的文件進行轉碼 通過include來配置,效率比 exclude 要高 
   },
  ]
 }
}

4、公共模塊的提取配置文件如下

plugins配置如下

const webpackConfig = {
 plugins: [
 new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks (module) {
    return (
      module.resource &&
      /\.js$/.test(module.resource) &&
      module.resource.indexOf(
        path.join(__dirname, '../node_modules')
      ) === 0
    )
  }
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest',
  minChunks: Infinity
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: 'app',
  async: 'vendor-async',
  children: true,
  minChunks: 3
 }),
]
}

主要是目的是將第三方依賴抽取到公共模塊放到vendor.js,然後針對動態引入的靜態文件做進一步的抽離放到 manifest.js 中

 

5、多進程轉碼

具體用法和配置如下:

const HappyPack = require('happypack') // 引入第三方依賴
const happyThreadPool = HappyPack.ThreadPool({size: 5}) // 設定五個線程池這裏默認設置5個進程
module.exports = {
 plugins: [
    new HappyPack({
      id: 'happyBabel', // 定義唯一id
      threadPool: happyThreadPool, // 指定進程池
      loaders: ['babel-loader?cacheDirectory=true']
    }),
  ],
 module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'happypack/loader?id=happyBabel', // 通過唯一id進行查找
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      },
    ]
 }
}



6、按需加載配置如下,實際生產中減少渲染壓力

{
     path: '/test',
     name: 'test',
     component: resolve => require(['@/test'], resolve)
}

7、DllPlugin 插件的使用(這裏提供簡單的配置,具體根據實際需要)
首先在你的build文件加下新建 webpack.dall.config.js 文件,內容如下

const path = require('path')
const webpack = require('webpack')

module.exports = {
  entry: {
    vendor: [
      'aws-sdk',
      'axios',
      'moment',
      'vue',
      'vue-awesome-swiper',
      'vue-router',
      'vuex',
    ]
  },
  output: {
    path: path.resolve(__dirname, '../static'), // 這裏通過絕對路徑指定生成文件
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.resolve(__dirname, '../static', '[name]-manifest.json'),
      name: '[name]_library'
    }),
  ]
} 

控制檯輸入 webpack --config build/webpack.dall.config.js
或者 在package.json文件中進行如下配置 運行 npm/cnpm/yarn build build:dall

"scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "test": "cross-env NODE_ENV=test env_config=test node build/build.js",
    "lint": "eslint --ext .js,.vue src",
    "build": "cross-env NODE_ENV=production env_config=prod node build/build.js",
    "build:dall": "webpack --config build/webpack.dall.config.js"
  },

將會看到static目錄項生成 vendor.dall.js 和 vende-manifest.json文件,生成文件如下

接下來在生 build 下的 webpack.prod.conf.js 進行引用

到這個時候我們進行一口深呼吸,以爲打工打工告成,結果發現每次打包,然並卵,各位可憐的程序員,別急,萬里長征還剩最後一步,生成的js文件你不引用還能怪誰啊親

看清楚了怎麼引用

找到你的index.html文件手動引入 vendor.dll.js如下

第一次運行速度依然沒啥改變,當你再次運行的時候你會有飛一般的感覺
 

8、Gzip 文件壓縮 根據實際情況,具體配置如下

if (config.build.productionGzip) {
  const CompressionWebpackPlugin = require('compression-webpack-plugin')

  webpackConfig.plugins.push(
    new CompressionWebpackPlugin({
      asset: '[path].gz[query]',
      algorithm: 'gzip',
      test: new RegExp(
        '\\.(' +
        config.build.productionGzipExtensions.join('|') +
        ')$'
      ),
      threshold: 10240,
      minRatio: 0.8
    })
  )
}



以上是個人在實際生產項目中的webpack打包以及代碼壓縮的優化,從一開始的發版打包項目 接近一份到到 20幾秒將近一半時間的縮短,從一開始發版後端人員的抱怨:好沒好,你們打包這麼這麼慢 到 我靠!!!這麼快就好了。這是一種自我價值的體現和別人對你的肯定。

 

第一次寫博客,如有不妥之處歡迎大家批評指正,每一個優化點的原理就不再這裏細說了,先把效率搞上去,原理自行理解啊,個人對部分也不是特別清楚

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章