webpack5 新特性

1:剔除npm包里面針對Node.js模塊自動引用的Polyfills

v4編譯引入npm包,有些npm包里面包含針對nodejs的polyfills,實際前端瀏覽器是不需要的
例如:

// index.js
import CryptoJS from 'crypto-js';
const md5Password = CryptoJS.MD5('123123');
console.log(md5Password);

v4 引入crypto-js模塊會自動引入polyfill: crypto-browserify, 但部分代碼是不需要的,v5 默認會自動剔除
v5編譯中,會出現(xiàn)polyfill添加提示,如果不需要node polyfille,按照提示 alias 設置為 false 即可

// webpack.config.js
  resolve: {
    // 1.不需要node polyfilss
    alias: {
      crypto: false
    },
    // 2.手動添加polyfills
    // fallback: {
    //   "crypto": require.resolve('crypto-browserify')
    // }
  }

2:長期緩存優(yōu)化,

以前v4是根據(jù)代碼的結(jié)構(gòu)生成chunkhash,現(xiàn)在v5根據(jù)完全內(nèi)容生成chunkhash,比如改了內(nèi)容的注釋或者變量則不會引起chunkhash的變化,讓瀏覽器繼續(xù)使用緩存
1:moduleId改為根據(jù)上下文模塊路徑計算,chunkId根據(jù)chunk內(nèi)容計算
2: 為module,chunk 分配確定的(3或5位)數(shù)字ID,這是包大小和長期緩存之間的一種權(quán)衡

3:持久化緩存

1:第一次構(gòu)建是一次全量構(gòu)建,它會利用磁盤模塊緩存(以空間換時間),使得后續(xù)的構(gòu)建從中獲利。
2:后續(xù)構(gòu)建具體流程是:讀取磁盤緩存 -> 校驗模塊 -> 解封模塊內(nèi)容。

v5 默認情況,緩存配置是memory,修改設置為filesystem, 將緩存寫入硬盤

// webpack.config.js
module.exports = { 
  cache: {
    // 1. 將緩存類型設置為文件系統(tǒng)
    type: 'filesystem', // 默認是memory
    // 2. 將緩存文件夾命名為 .temp_cache,
    // 默認路徑是 node_modules/.cache/webpack
    cacheDirectory: path.resolve(__dirname, '.temp_cache')
  }
}

4: 模板聯(lián)邦

跨項目間的chunk可以相互共享
1:UMD 模塊

<script  src="https://unkpg.com/lodash.js"></script>

2: 微前端:多個項目共存于一個頁面,有點類似iframe,共享的對象是項目級的,頁面級的
子應用間的chunk以及對象可通過全局事件共享,但是公共包在項目安置以及打包編譯很難放

  子應用獨立打包,模塊解耦了,但公共的依賴不易維護處理
  整體應用一起打包,能解決公共依賴;但龐大的多個項目又使打包變慢,后續(xù)也不好擴展

3:v5 的模塊共享
這個方案是直接將一個應用的 bundle,應用于另一個應用,動態(tài)分發(fā) runtime 子模塊給其他應用。
模塊聯(lián)邦的使用方式如下:

module.exports = {
  // other webpack configs...
  plugins: [
    new ModuleFederationPlugin({
      // 1. name 當前應用名稱,需要全局唯一
      name: "app_one_remote",
      // 2. remotes 可以將其他項目的 name 映射到當前項目中
      remotes: {
        app_two: "app_two_remote",
        app_three: "app_three_remote"
      },
      // 3. exposes 表示導出的模塊,只有在此申明的模塊才可以作為遠程依賴被使用
      exposes: {
        AppContainer: "./src/App"
      },
      // 4. shared可以讓遠程加載的模塊對應依賴改為使用本地項目的 React或ReactDOM。
      shared: ["react", "react-dom", "react-router-dom"]
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
      chunks: ["main"]
    })
  ]
};

比如設置了remotes: { app_two: "app_two_remote" },在代碼中就可以直接利用以下方式直接從對方應用調(diào)用模塊

import { Search } from "app_two/Search";
app_two/Search來自于app_two 的配置:

// app_two的webpack 配置
export default {
  plugins: [
    new ModuleFederationPlugin({
      name: "app_two",
      library: { type: "var", name: "app_two" },
      filename: "remoteEntry.js",
      exposes: {
        Search: "./src/Search"
      },
      shared: ["react", "react-dom"]
    })
  ]
};

正是因為 Search在exposes被導出,我們因此可以使用 [name]/[exposes_name] 這個模塊,這個模塊對于被引用應用來說是一個本地模塊。

4:構(gòu)建優(yōu)化 — 更好的Tree Shacking

v4 有些場景是不能將無用代碼剔除的
1: 對于模塊引入嵌套場景,如下b 是不會出現(xiàn)在生產(chǎn)代碼里面的

// one.js
export const a = 1;
export const b = 2;

// two.js
import * as inner from "./inner";
export { inner }

// three.js
import * as module from "./module";
console.log(module.inner.a);

2:只有 test 方法使用了 someting 。最終可以實現(xiàn)標記更多沒有使用的導出項

import { something } from "./something";

function usingSomething() {
return something;
}

export function test() {
return usingSomething();
}

3: Commondjs?,F(xiàn)在Webpack不僅僅支持 ES module 的 tree Shaking,commonjs規(guī)范的模塊開始支持了


更細致的講解參考:
https://zhuanlan.zhihu.com/p/264826929
https://blog.csdn.net/P6P7qsW6ua47A2Sb/article/details/110015183

webpack dll: 將第三方庫打包成dll.js ,這樣修改應用代碼只會構(gòu)建應用的chunk,無關(guān)dll.js,加快速度,且瀏覽器緩存利好
https://www.cnblogs.com/skychx/p/webpack-dllplugin.html

hard-source-wepack-plugin:
https://segmentfault.com/a/1190000022453801

webpack 常用知識點
https://juejin.cn/post/6844904007362674701

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容