Представляем webpck5
С момента запуска webpack5 прошло больше года, а он все еще находится в стадии бета-версии, его можно установить и использовать уже сейчас.
Способ установки
```
npm install webpack@next webpack-cli -D
yarn add webpack@next webpack-cli -D
```
HTML-плагин, совместимый с HTML
- нужно быть
html-webpack-plugin
Обновление до версии 4.3.0
Требования к окружающей среде
- Последняя официальная документация требует, чтобы узел был как минимум версии 10.13.0 или выше.
Внедрение новых функций
- постоянный кеш
- Оптимизация идентификаторов модулей и идентификаторов блоков
- Умнее встряхивать деревья
- Скрипт nodeJs polyfill удален
- Поддержка генерации кода для e6/es2015
- SplitChunk и размер модуля
- Module Federation
Используйте опыт
- После начала работы webpack 5 имеет очень хороший размер пакета, непрерывную скорость компиляции и совместим с webpack 4. Module Federation также предоставляет решение для использования микроинтерфейсных приложений в проектах. Если вы столкнулись с несовместимостью в процессе обновления, вы можете перейти кжурнал изменений webpack5Проверьте это.
постоянный кеш
- До webpack5 можно было использовать
cache-loader
Запишите скомпилированную структуру в кеш жесткого диска, вы также можете использоватьbabel-loader
,настраиватьoption.cacheDirectory
Будуbabel-loader
Результат компиляции записывается на диск. - В webpack5 кеш включен по умолчанию, а кеш по умолчанию находится в памяти. Кэш можно установить
module.export={
cache{
type:'filesystem', // 'memory' | 'filesystem'
cacheDirectory: 'node_modules/.cache/webpack', // 默认将缓存存储在 node_modules/.cache/webpack
// 缓存依赖,当缓存依赖修改时,缓存失效
buildDependencies:{
// 将你的配置添加依赖,更改配置时,使得缓存失效
config: [__filename]
}
}
}
-
По умолчанию webpack предполагает, что каталог node_modules, в котором он находится, изменяется только менеджером пакетов, пропускает хэширование и обработку временных меток и использует только имя и версию пакета из соображений производительности.
-
Когда cache.type: "filesystem" установлен, webpack внутренне включает кэширование файловой системы и кэширование памяти в иерархическом порядке. При чтении из кеша сначала проверяется кеш памяти, и если кеш памяти не найден, он понижается до кеша файловой системы. Кэш записи будет записывать как в кеш памяти, так и в кеш файловой системы.
-
Кэш файловой системы напрямую не сериализует запросы на запись на диск. Он будет ждать завершения процесса компиляции и бездействия компилятора перед выполнением. Причина этого в том, что сериализация и запись на диск требуют больших ресурсов, и мы не хотим дополнительно затягивать процесс компиляции.
-
Разработка стратегии устранения кеша: файловый кеш хранится в node_modules/.cache/webpack.Для набора кеша максимальное количество кэшированного содержимого не должно превышать 5, а максимальное накопленное использование ресурсов не должно превышать 500 МБ.При приближении или превышении порог 500 МБ, приоритет отдается удалению самого старого кэшированного содержимого. При этом эффективная продолжительность кэша также рассчитана на 2 недели.
Оптимизация идентификаторов модулей и идентификаторов блоков
чанк и модуль
- Чанк: webpack упаковывает окончательно сгенерированные отдельные фрагменты файлов, окончательно сгенерированные отдельные файлы, один файл соответствует одному фрагменту.
- модуль: каждый исходный файл js фактически можно рассматривать как модуль.
Недостатки chunkId
- веб-пакет5 улучшен
moduleIds
а такжеchunkIds
Ok. До webpack5 не былоentry
Упакованные файлы фрагментов будут выводиться с использованием метода именования файлов 1, 2, 3... . (Значение хеша после имени файла генерируется с помощью chunkhash)
- Это приведет к тому, что когда файл 1.js будет удален или временно не используется, то 2.js->1.js, 3.js->2.js, что вызовет исходный онлайн 2.js Кэш будет быть признаны недействительными по запросу.
- Также можно пройти перед webpack5
webpackChunkName
решить проблему с названием
...
<Switch>
<Route key='/' exact path='/' component={
Loadable({
loader: () => import(/* webpackChunkName: "home" */ './home'),
loading: (<div>loadding</div>)
})
}/>
<Route key='/page1' exact path='/page1' component={
Loadable({
loader: () => import(/* webpackChunkName: "page1" */'./page1'),
loading: () => (<div>loadding</div>)
})
} />
<Route key='/page2' exact path='/page2' component={
Loadable({
loader: () => import(/* webpackChunkName: "page2" */'./page2'),
loading: () => (<div>loadding</div>)
})
} />
</Switch>
....
- Кажется, это решает проблему инвалидации кеша, но когда мы откроем скомпилированный файл home.js, мы обнаружим, что chunkId все еще существует. Если домашнее меню удалено, упакованный chunkId страницы 1 и страницы 2 все равно изменится.
- Файл, упакованный page1.js
- Файл, упакованный page1.js после удаления home.js
- Даже если page1.js не был изменен, чанкхаши page1.js все равно изменится из-за изменения chunkId, вызванного удалением home.js, и проблема инвалидации кеша все еще существует.
Улучшения в webapck5
- С новым алгоритмом в рабочем режиме эти функции включены по умолчанию.
chunkIds: "deterministic", moduleIds: "deterministic"
. - Этот алгоритм присваивает короткие числовые идентификаторы (3 или 4 символа) модулям и фрагментам детерминированным образом. Это основано на компромиссе между размером пакета и долгосрочным кэшированием.
optimization.moduleIds:
可选值:
1. false 告诉webpack不应使用任何内置算法,通过插件提供自定义算法
2.natural 按使用顺序的数字ID。
3.named 方便调试的高可读性id
4.deterministic 根据模块名称生成简短的hash值
5.size 根据模块大小生成的数字id
optimization.chunkIds:
可选值:
1. false 告诉webpack不应使用任何内置算法,通过插件提供自定义算法
2.natural 按使用顺序的数字ID。
3.named 方便调试的高可读性id
4.deterministic 根据模块名称生成简短的hash值
5.size 根据请求到的初始资源size计算的id
6..total-size:根据请求到的解析资源size计算的id
Умнее встряхивать деревья
- Условия включения встряхивания дерева такие же, как и в webpack 4. Для включения производственной среды необходимо использовать модульность ES6.
- пример
// a.js
export const a =22;
export const b = 33;
// b.js
import * as a from './a.js'
export {a};
// index.js
import * as b from './b.js'
console.log(b.a.a) // 输出22
- webpack4: при упаковке будет
const b =33
также упакован в
- webpack5: упакованный код более оптимизирован
Скрипт nodeJs polyfill удален
- webpack
- Хотя это упрощает написание модулей для Node.js, в пакет добавляется слишком большой полифилл. Во многих случаях эти полифилы не нужны.
import CryptoJS from 'crypto-js';
console.log(CryptoJS.MD5('123123'));
- веб-пакет4:
- веб-пакет5:
Поддержка генерации кода для e6/es2015
- webpack5 недавно добавил ecmaVersion в вывод, установил
output: { ecmaVersion: 6 }
Его можно использовать, код, сгенерированный при компиляции по умолчанию в webpack, соответствует версии es5. - Два метода настройки:
5 =< ecmaVersion <= 11
2009 =< ecmaVersion <= 2020
SplitChunk и размер модуля
- Модули теперь могут лучше представлять размеры вместо того, чтобы показывать одно число и разные типы размеров.
- По умолчанию обрабатываются только размеры javascript, но теперь вы можете передавать несколько значений для управления ими:
optimization{
splitChunks{
minSize: {
javascript: 30000,
style: 50000,
}
}
}
Module Federation
- Федерация модулей позволяет приложению JavaScript динамически загружать код из другого приложения JavaScript при совместном использовании зависимостей. Позвольте коду напрямую делиться между проектами с помощью CDN, больше не нужно устанавливать пакет Npm локально, создавать и публиковать его!
- Динамическая загрузка позволяет коду загружать код другого приложения по запросу во время выполнения.
- Пример: компонент кнопки, представленный в app2, упоминается в app1.
// app1 - webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
//....
plugins: [
new ModuleFederationPlugin({
name: "app1", // 应用名称 唯一
library: { type: "var", name: "app1" },
remotes: { // 需要引用远程应用,与app2中library的name字段保持一致
app2: "app2",
},
shared: ["react", "react-dom"], // 先判断存不再存这个包,如果不存在就使用app2里的依赖
}),
],
};
// app2 - webpack.config.js
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
module.exports = {
//....
plugins: [
new ModuleFederationPlugin({
name: "app2", // 应用名称 唯一
library: { type: "var", name: "app2" }, // UMD标准导出,和name保持一致即可。
filename: "remoteEntry.js", 暴露出去的chunkname
exposes: { 要暴露出去的模块
"./Button": "./src/Button",
},
shared: ["react", "react-dom"], 与app1共享的依赖,如果app1中有,则会优先使用app1中的依赖。(注:被app1引用)时候会按照app1的/package.json中的版本要求来加载
}),
],
};
// app1/index.html
// 引入app2暴露的文件
...
<head>
<srcipt src="http://localhost:3002/remoteEntry.js"></script>
</head>
...
app1/app.js
import AppTwoButton from 'app/Button';
const App = ()=>{
return (
<AppTwoButton/>
)
}
app1/bootstrap.js
ReactDOM.render(<App />, document.getElementById("root"));
app1/bootstrap.js
import("./bootstrap");
- Понимание федерации модулей из процесса загрузки
- Первое, что нужно загрузить, это app2/remoteEntry.js, потому что он загружается в html.Просматривая remoteEntry.js, можно увидеть, что webpakc определяет app2 в глобальной переменной, так что app1 может загружать модули в app2.
- Загрузите упакованный main.js app1, введите bootstrap.js, чтобы найти зависимости, проанализировать
- Затем загрузите react.js и react-dom в main.js, prop-types.js, реакция которых зависит от
- Затем, когда я прошел через пульт, я нашел компонент Button, который зависит от app2.
- После загрузки всех зависимостей bootstrap.js асинхронная загрузка завершается, выполняется логика then и запускается приложение.
Суммировать
- Федерация модулей предлагает новые идеи для микроинтерфейсов, сегментации кода, общих зависимостей, загрузки по требованию и может быть загружена во время выполнения. Но недостатком являются общедоступные глобальные переменные и глобальные стили, а предоставление модулей глобальным переменным недостаточно элегантно.
- Webpack5 все еще находится в процессе слияния кодов.Текущая версия - bate22.После выхода официальной версии webpack5 я полагаю, что функция Module Federation будет продолжать оптимизироваться. Короче говоря, после обновления webpack5 скорость сборки и объем упаковки значительно улучшились.
использованная литература
- 1. Исследование трех основных сценариев приложений, углубленный анализ новой функции Webpack Module Federation:developer.aliyun.com/article/755…
- 2. Практическая оценка Webpack5nuggets.capable/post/684490…