webpack簡單優化的配置

webpack性能優化

1.開發環境新能優化

1.1優化打包構建速度

1.1.1 HMR: hot module replacement / 熱模板替換

作用: 一個模板發生變化,只會重新打包這一個模塊(默認是打包所有)

1.2優化代碼調試

1.1.2 source-map

作用: 一種提供源代碼到構建後代碼映射技術 (如果 構建後代碼出錯了 可以通過映射追蹤源代碼錯誤)

2. 生產環境性能優化

2.1優化打包構建速度

2.1.1 開啓babel緩存

cacheDirectory: true,
讓第二次打包更快,綁定contenthash值讓線上運行緩存更好使

{
    test: /\.js$/,
    exclude: /node_modules/,
    loader: 'babel-loader',
    options: {
      // 預設  指示babel做怎麼樣的兼容性處理
      presets: [
        ['@babel/preset-env',
          {
            useBuiltIns: 'usage', // 按需加載
            corejs: { version: 3 }, // 制定corejs的版本
            targets: { // 指定具體的兼容性的版本
              chrome: '60',
              firefox: '60',
              ie: '9',
              safari: '10',
              edge: '17',
            },
          },
        ],
      ],
      // 開啓babel緩存
      // 第二次構建時 會讀取之前的緩存
      // 需要給 輸出文件帶上contnenthash值  不然無法更新變化
      cacheDirectory: true,
    },
},

  1. hash:每次webpack構建時會生成一個唯一的hash值,js和css同一個.
  2. chunkhash: 根據chunk生成的hash值,如果打包的來源於同一個chunk,那麼chuankhash值就是一樣的,js和css的還是一樣的
  3. contenthash: 根據文件內容生成的hash值.不同文件hash值不一樣

2.1.2 多進程打包 thread-loader

多用babel-loader 啓動時間大概爲600ms 只有工作消耗時間比較長的才需要多進程打包

一定要放在需要多進程的loader後面

{
  /**
   * 開啓多進程打包。
   * 啓動時間大概爲600ms
   * 只有工作消耗時間比較長的才需要多進程打包
   */
  loader: 'thread-loader',
  options: {
    workers: 2, // 進程2個
  },
}

2.1.3 externals

忽略文件,不進行打包

externals: {
//拒絕jq被打包進來
//線上的需要通過cdn引入這個包
    jquery:'jQuery'
}

2.1.4 dll

使用dll技術,對某些庫(第三方庫:jq,react,vue…)進行單獨打包,只用打包一次,之後就不用打包了

注意:當運行webpack時,默認查找webpack.config.js配置文件

需要運行webpack.dll.js文件 要指定
–> webpack --config webpack.dll.js

<!--webpack.dll.js文件-->
const {resolve} = require('path')
const webpack = require('webpack')
module.export = {
    entry: {
        //最終打包生成的[name]--> jquery
        //['jquery',xxx]-->要打包的庫
        jquery:['jquery',xxx]
    },
    output: {
        filename: '[name].js',
        path: resolve(__dirname,'dll'),
        //打包庫裏面向外面暴露出去的內容叫什麼名字
        library:'[name]_[hash]'
    },
    plugins:[
        new webpack.Dllplugin({
           //映射庫暴露的內容名稱 name:'[name]_[hash]',
            path: resolve(__dirname, 'dll/manifest.json')
        })
    ],
    mode: 'production'
}
<!--webpack.config.js文件-->
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const AddassetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')
module.export = {
    entry:'./src/index.js',
    output: {
        filename: 'built.js',
        path: resolve(__dirname,'build'),
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:'./src/index.html'
        }),
        //告訴webpack那些庫不參與打包,同時使用名稱時也得變
        new webpack.DllReferencePlugin({
            manifest: resolve(__dirname,'dll/manifest.json')
        })
        //將某個文件打包出去。並在html中自動引入資源
        new AddassetHtmlWebpackPlugin({
            filepath: resovle(__dirname,'dll/jquery.js')
        })
    ],
    mode: 'production'
}

2.2優化代碼運行性能

2.2.1 oneOf

module:{
    rules:[
        {
            test: /\.js$/,
            exclude: /'node_modules'/,
            enforce: 'pre', // 優先執行
            loader: 'eslint-loader',
            options: {
              // 自動修復
              fix: true,
            },
        },
        {
         oneOf:[
            {
                exclude: /\.(css|js|html|less|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                  outputPath: 'font',
                },
             },
         ]
        } 
    ]
}

不用oneOf的話 每個文件都要被所有Loader過濾一遍,注意:不能有兩個配置處理一中類型的文件

  1. 正常來說 一個文件只能被一個loader處理
  2. 當要被多個Loader處理的時候 需要弄清執行的順序 比如 先要 執行 eslint 在執行babel轉換 ,不然 先babel轉換成es5的話,再eslint回報錯
  3. 使用enforce:'pre’屬性,提到oneOf外面

2.2.2 tree shaking 去除無用代碼

注意: 1.必須使用es6模塊化 2.開啓production環境

作用: 減少代碼體積,會自動刪除沒有使用的代碼,使用production時會自動開啓,

防止css被刪除,需要在package.json中配置:
“sideEffects”:["*.css"]

2.2.3 code split代碼分割

分割成多個js文件,實現並行加載 速度更快

2.2.3.1 從入口入手
entry:{
//多個入口 多個bundle  多頁面
//單頁面 則單入口
    main:'./src/js/index.js',
    test:'./src/js/test.js',
},
output: {
    //[name]文件名
    fileName:'js/[name].[contenthash:10].js',
    path: resolve(_dirname,'build')
}
2.2.3.1 optimization
// 可以將node_module中代碼單獨打包成一個chunk輸出(單入口)
//可以自動分析多入口chunk中,公共文件,有可以單獨打包成一個chunk,不會重複的打包多次(多入口)
optimization:{
    splitChunks:{
        chunks:'all'
    }
}

//單入口 引入js打包成單獨的
// import動態導入 
import(/* webpackChunkName:'test' */'./test')
.then(()=>{文件加載成功})
.catch(()=>{文件加載失敗})

2.2.3 懶加載

//js懶加載 需要使用時候才加載
document.getElementById('btn').onclick = function () {
  import( /* webpackChunkName:'ppp' */ './ppp').then(({
    add
  }) => {
    add(4, 6)
  })
}

2.2.4預加載

//js預加載 webpackPrefetch  會在使用之前提前加載 等其他資源加載完畢 再偷偷加載
document.getElementById('btn').onclick = function () {
  import( /* webpackChunkName: 'test',webpackPrefetch: true */ './ppp' ).then(({
    add
  }) => {
    add(4, 6)
  })
}

2.2.5 PWA 漸進式網絡開發應用程序

workbox --> workbox-webpack-plugin

<!--config.js-->
    new WorkboxWebpackPlugin.GenerateSW({
      // 幫助serverwork快速啓動   刪除舊的serverwork
      // serverwork配置文件  一般在入口文件中配置
      clientsClaim: true,
      skipWaiting: true,
    }),
    
<!--index.js-->

//註冊serverwork
//需要處理兼容性問題
//eslint不認識window等全局變量
// "env": {
//   "browser": true  //支持瀏覽器
// }
if ('serverWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serverWorker.register('/service-worker.js')
      .then(() => {
        console.log("serverworker註冊成功")
      })
      .catch(() => {
        console.log("serverworker註冊失敗")
      })
  })
}
<!--package.json(eslint)-->
  "eslintConfig": {
    "extends": "airbnb-base",
    "env": {
      "browser": true
    }
  },
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章