Плагин объединения модулей
В прошлом, одним из компромиссов webpack при объединении было то, что каждый модуль в вашем пакете был обернут в отдельные функции-замыкания. Эти функции-обёртки делали выполнение JavaScript в браузере медленнее. В сравнении, такие инструменты, как Closure Compiler и RollupJS, «поднимают» или объединяют область действия всех ваших модулей в одно замыкание, что позволяет вашему коду выполняться быстрее в браузере.
Этот плагин позволит использовать тот же механизм объединения в webpack. По умолчанию этот плагин уже включен в режиме производства mode и отключён в противном случае. Если вам нужно переопределить оптимизацию в режиме производства mode, установите optimization.concatenateModules параметр в значение false. Чтобы включить поведение объединения в других режимах, вы можете добавить ModuleConcatenationPlugin вручную или использовать optimization.concatenateModules параметр:
new webpack.optimize.ModuleConcatenationPlugin();
Это поведение объединения называется «подъёмом области видимости».
Подъём области видимости — это функция, которая стала возможной благодаря синтаксису модулей ECMAScript. Из-за этого webpack может перейти к обычному объединению, в зависимости от того, какие модули вы используете, и других условий.
Отказы оптимизации
Как объясняется в статье, webpack пытается достичь частичного подъёма области видимости. Он будет объединять модули в одну область видимости, но не всегда может этого добиться. Если webpack не может объединить модуль, существуют два варианта: предотвратить объединение и создать новую группу модулей. Следующие условия определяют результат:
| Условие | Результат |
|---|---|
| Не модуль ES6 | Предотвратить |
| Импортируется не импортирующим модулем | Создать новую группу |
| Импортируется из другого раздела | Создать новую группу |
| Импортируется множеством других групп модулей | Создать новую группу |
Импортируется с import() |
Создать новую группу |
Воздействует на ProvidePlugin или использует module |
Предотвратить |
| Принято HMR | Создать новую группу |
Используется eval() |
Предотвратить |
| В нескольких разделах | Предотвратить |
export * from "cjs-module" |
Предотвратить |
Алгоритм группирования модулей
Следующий псевдо-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;
} Отладка отказов оптимизации
При использовании webpack CLI, флаг --stats-optimization-bailout отобразит причины отказа. При использовании webpack конфигурации, добавьте следующее в stats объект:
module.exports = {
//...
stats: {
// Display bailout reasons
optimizationBailout: true,
},
};
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/plugins/module-concatenation-plugin