1. 程式人生 > >webpack實戰專案中程式碼打包和優化總結

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幾秒將近一半時間的縮短,從一開始發版後端人員的抱怨:好沒好,你們打包這麼這麼慢 到 我靠!!!這麼快就好了。這是一種自我價值的體現和別人對你的肯定。

 

更多的乾貨請點選這裡 https://blog.csdn.net/woleigequshawanyier

歡迎各位看官的批評和指正,共同學習和成長

希望該文章對您有幫助,也希望得到您的鼓勵和支援