ModuleConcatenationPlugin

2023-06-03 14:51 更新

在過去,webpack在捆綁時的一個權(quán)衡是,你的捆綁包中的每個模塊都將被包裝在單獨的函數(shù)閉包中。這些包裝器函數(shù)降低了JavaScript在瀏覽器中的執(zhí)行速度。相比之下,像Closure Compiler和RollupJS這樣的工具可以將所有模塊的作用域“提升”或連接到一個閉包中,并允許你的代碼在瀏覽器中有更快的執(zhí)行時間。

這個插件將在webpack中啟用相同的連接行為。默認情況下,該插件已在生產(chǎn)模式下啟用,否則禁用。如果需要覆蓋生產(chǎn)模式優(yōu)化,請設置 ?optimization.concatenateModules? 選擇為 ?false?。要在其他模式下啟用連接行為,您可以手動添加 ?ModuleConcatenationPlugin? 或使用優(yōu)化。optimization.concatenateModules 選擇:

new webpack.optimize.ModuleConcatenationPlugin();

這種連接行為稱為“作用域提升”。作用域提升是ECMAScript模塊語法實現(xiàn)的一個特性。因此,webpack可能會根據(jù)您使用的模塊類型和其他條件退回到正常的捆綁。

Optimization Bailouts

正如文章所解釋的,webpack試圖實現(xiàn)部分作用域提升。它會將模塊合并到單個作用域中,但不能在所有情況下都這樣做。如果webpack不能合并一個模塊,兩個替代選項是Prevent和Root。Prevent意味著模塊必須在它自己的作用域中。Root表示將創(chuàng)建一個新的模塊組。以下條件決定了結(jié)果:

Condition Outcome
Non ES6 Module Prevent
Imported By Non Import Root
Imported From Other Chunk Root
Imported By Multiple Other Module Groups Root
Imported With import() Root
Affected By ProvidePlugin Or Using module Prevent
HMR Accepted Root
Using eval() Prevent
In Multiple Chunks Prevent
export * from "cjs-module" Prevent

Module Grouping Algorithm

下面的偽JavaScript解釋了該算法:

modules.forEach((module) => {
  const group = new ModuleGroup({
    root: module,
  });
  module.dependencies.forEach((dependency) => {
    tryToAdd(group, dependency);
  });
  if (group.modules.length > 1) {
    orderedModules = topologicalSort(group.modules);
    concatenatedModule = new ConcatenatedModule(orderedModules);
    chunk.add(concatenatedModule);
    orderedModules.forEach((groupModule) => {
      chunk.remove(groupModule);
    });
  }
});

function tryToAdd(group, module) {
  if (group.has(module)) {
    return true;
  }
  if (!hasPreconditions(module)) {
    return false;
  }
  const nextGroup = group;
  const result = module.dependents.reduce((check, dependent) => {
    return check && tryToAdd(nextGroup, dependent);
  }, true);
  if (!result) {
    return false;
  }
  module.dependencies.forEach((dependency) => {
    tryToAdd(group, dependency);
  });
  group.merge(nextGroup);
  return true;
}

Debugging Optimization Bailouts

當使用webpack CLI時,?——stats-optimization-bailout? 標志將顯示救助原因。當使用webpack配置時,在 ?stats? 對象中添加以下內(nèi)容:

module.exports = {
  //...
  stats: {
    // Display bailout reasons
    optimizationBailout: true,
  },
};


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號