Через два года WebPack 5 официально выпущен!

внешний интерфейс Webpack
Через два года WebPack 5 официально выпущен!

Привет, после Vue 3 и React 17 я снова приду! Выходные данные китайский ужеСинхронизация и перевод китайской документации webpack v5 завершены, и вы можете без труда ее прочитать.

Найдите адрес документа:webpack.docschina.org

Найдите адрес документа:webpack.docschina.org

Найдите адрес документа:webpack.docschina.org

Трижды сказано важное, наши документы принадлежат официалам, других доменных имен у нас нет, и он синхронизируется с официалами в режиме реального времени.

10 октября 2020 года веб-пакет был обновлен до версии 5.0, а на официальный сайт добавлен каталог блогов. Мы синхронизировались по времени, и эта статья — та версия, которую мы подытожили после прочтения. Без лишних слов начните текст.

С момента выпуска webpack4 в феврале 2018 г. никаких крупных обновлений веб-пакета на данный момент не было.В целях сохранения согласованности API старая архитектура не сильно изменилась, оставив много багажа. После более чем 2-х летнего отсутствия, 10 октября 2020 года, был официально выпущен webpack 5, который принес множество серьезных изменений, которые значительно повысят эффективность строительства и качество работы фронтенд-инженеров.

Общее направление развития этого крупного релиза выглядит следующим образом:

  • Попробуйте постоянное кэширование, чтобы улучшить производительность сборки.
  • Попробуйте улучшить долгосрочное кэширование с помощью лучших алгоритмов и значений по умолчанию.
  • Попробуйте увеличить размер пакета с помощью улучшения Tree Shake и генерации кода.
  • Попытка улучшить совместимость с веб-платформами.
  • Попытка очистить те внутренности, которые были в странном состоянии при реализации функций v4, без внесения каких-либо критических изменений.
  • Попытка подготовиться к будущим функциям, внося критические изменения сейчас, оставаясь на версии 5 как можно дольше.

webpack 5изRelease NoteОчень длинная, эта статья пытается извлечь самую краткую информацию.

1. Функция очистки

1.1 Очистка устаревших функций

все вwebpack 4Все функции, помеченные как истекающие, были удалены в этой версии. Итак, переход наwebpack 5Прежде чем убедиться, что выwebpack 4Запустите сборку без каких-либо устаревших предупреждений.

1.2 Полифилы больше не ссылаются автоматически для модулей Node.js.

больше никогдаNode.jsВстроенные модули добавляются автоматическиPolyfills. Референции в любом проектеNode.jsвстроенные модули, вwebpack 4или был добавлен автоматически в предыдущих версияхPolyfills. ноwebpack 5не будет делать это снова,webpackПриложим больше усилий для совместимости интерфейсных модулей.

Если у вас есть ссылки на них в вашем кодеNode.jsмодули, которые необходимо обновить доwebpack 5, постараюсь использовать интерфейсные модули, или вручную добавить подходящиеPolyfills.

Для разработчиков этих библиотек, пожалуйста, обратитесь кpackage.jsonопределено вbrowserполе, чтобы библиотеку классов можно было применить во внешнем интерфейсе.

2. Оптимизация для долгосрочного кэширования

2.1 Определенный фрагмент, идентификатор модуля и имя экспорта

Добавлен алгоритм долгосрочного кэширования. Эти алгоритмы включены по умолчанию в производственном режиме.

chunkIds: "deterministic" moduleIds: "deterministic" mangleExports: "deterministic"

Алгоритм назначает короткие (3 или 5 цифр) числовые идентификаторы модулям и частям детерминированным образом, что является компромиссом между размером пакета и долгосрочным кэшированием. Поскольку в этих конфигурациях будут использоваться детерминированные идентификаторы и имена, это означает, что результирующие кэши не станут недействительными чаще.

2.2 Истинный хэш содержимого

когда используешь[contenthash], Webpack 5 будет использовать реальный хэш содержимого файла. Раньше он «только» использовал хэш внутренней структуры. Это положительно влияет на долгосрочное кэширование, когда изменяются только аннотации или переименовываются переменные. Эти изменения не видны после сжатия.

3. Улучшенная поддержка разработки

3.1 Идентификаторы кодовых блоков имен

В режиме разработки новый алгоритм идентификации именованных блоков, включенный по умолчанию, предоставляет удобочитаемые имена для модулей (и имен файлов). Идентификатор модуля определяется его путем относительноcontext. Идентификатор кодового блока определяется содержимым кодового блока.

Таким образом, вам больше не нужно использоватьimport(/* webpackChunkName: "name" */ "module")для отладки.但如果你想控制生产环境的文件名,还是有意义的。

Может использоваться в производственной средеchunkIds: "named"Используйте в рабочей среде, но убедитесь, что вы случайно не раскрываете конфиденциальную информацию об именах модулей.

Миграция: если вам не нравится менять имена файлов в процессе разработки, вы можете сделать это черезchunkIds: "natural"для использования старого числового режима.

3.2 Объединение модулей

Webpack 5 добавляет новую функцию «федерация модулей», которая позволяет нескольким сборкам webpack работать вместе. С точки зрения времени выполнения несколько встроенных модулей будут вести себя как гигантский граф связанных модулей. С точки зрения разработчика, модули можно импортировать из указанной удаленной сборки и использовать с минимальными ограничениями.

4. Поддержка новых функций веб-платформы

Для некоторой поддержки веб-платформы WebPack 5 также выполнил лучшее и улучшенные обновления.

4.1 Модуль JSON

Например, для модуля JSON он будет соответствовать текущему предложению и потребует экспорта по умолчанию, в противном случае появится предупреждающее сообщение. Даже при экспорте по умолчанию неиспользуемые свойстваoptimization.usedExportsОптимизация отбрасывается, атрибут будетoptimization.mangleExportsОптимизированный скремблирование.

Если вы хотите использовать собственный анализатор JSON, вы можетеRule.parser.parseУкажите собственный анализатор JSON для импорта файлов, подобных JSON (например, для toml, yaml, json5 и т. д.).

4.2 Ресурсный модуль

Webpack 5 теперь имеет встроенную поддержку модулей, представляющих активы. Эти модули могут отправить файл в выходную папку или внедрить DataURI в пакет javascript. В любом случае, они дают URL для работы.

Их можно использовать несколькими способами:

  • import url from "./image.png"И вmodule.ruleустановить вtype: "asset"При сопоставлении такого импорта. (старый метод)
  • new URL("./image.png", import.meta.url)(новый способ)

Синтаксис «New Way» был выбран, чтобы позволить запущенным кодом без упаковочных инструментов. Этот синтаксис также может использоваться в нативных модулях Ecmascript в браузере.

4.3 Поддержка нативных рабочих

при размещении ресурсовnew URLа такжеnew Worker/new SharedWorker/navigator.serviceWorker.registerПри объединении webpack автоматически создает новую точку входа для веб-воркера.

new Worker(new URL("./worker.js", import.meta.url))

Этот синтаксис также был выбран для того, чтобы код можно было запускать без инструментов упаковки. Этот синтаксис также доступен в собственных модулях ECMAScript браузера.

4.4 URIs

Webpack 5 поддерживает обработку протоколов в запросах.

  • служба поддержкиdata:. Поддерживается кодировка Base64 или необработанная. Mimetype можно найти вmodule.ruleсопоставляются с типами загрузчика и модуля. Например:import x from "data:text/javascript,export default 42".
  • служба поддержкиfile:.
  • служба поддержкиhttp(s):Но нужноnew webpack.experiments.s schemesHttp(s)UriPlugin()Выбрать в.
    • По умолчанию, когда целью является «Интернет», эти URI приводят к запросам к внешним ресурсам (которые являются внешними ресурсами).

Фрагменты в запросах поддерживаются. Например:./file.js#fragment.

4.5 Асинхронные модули

Webpack 5 поддерживает так называемые «асинхронные модули». Эти модули не разрешаются синхронно, а основаны на асинхронности и Promise.

Их импорт через «импорт» выполняется автоматически, никакого дополнительного синтаксиса не требуется, и разница едва заметна.

пройти черезrequire()Их импорт возвращает обещание, которое разрешается для экспорта.

В webpack есть несколько способов иметь асинхронные модули.

  • асинхронные внешние
  • Модули WebAssembly в новой спецификации
  • Модуль ECMAScript, использующий Await верхнего уровня.

4.6 Внешние ресурсы

Webpack 5 добавляет больше внешних типов, чтобы охватить больше приложений:

promise: выражение, результатом которого является обещание. Внешний модуль является асинхронным модулем, а проанализированное значение используется в качестве экспорта модуля.

import. оригинальныйimport()Используется для загрузки указанного запроса, внешний модуль является асинхронным модулем, а проанализированное значение экспортируется как модуль. Внешний модуль является асинхронным модулем.

module: Еще не реализовано, но планируется пройтиimport x from "..."Загрузите модуль.

script: пройти через<script>Тег загружает URL-адрес и получает вывод из глобальной переменной (и ее необязательных атрибутов). Внешний модуль является асинхронным модулем.

5. Новые экологические функции Node.js

теперь поддерживает package.json вexportsа такжеimportsполе. Yarn PnP теперь поддерживается по умолчанию.

Подробнее см.package exports.

6. Улучшение опыта разработки

6.1 Оптимизированные цели сборки

Webpack 5 позволяет передавать список целей и поддерживает целевые версии. Напримерtarget: "node14"``target: ["web", "es2020"].

Вот простой способ предоставить webpack всю информацию, необходимую для определения:

  • механизм загрузки блока кода и
  • Поддерживаемый синтаксис, такой как стрелочные функции

6.2 Статистика

Улучшена читаемость и избыточность формата статистического теста. Улучшенные значения по умолчанию, чтобы они были менее подробными, а также подходили для больших сборок.

6.3 Прогресс

ProgressPluginВ плагин также внесены некоторые оптимизации, теперь он может не только считать ход компиляции модуля, но и считать入口а также依赖. Кроме того, предыдущее отображение прогресса может оказывать определенное влияние на производительность сборки, и это обновление также внесло некоторые оптимизации производительности.

6.4 Автоматически добавлять уникальные имена

В webpack 4 несколько сред выполнения webpack могли столкнуться на одной и той же HTML-странице, потому что они используют одну и ту же глобальную переменную для загрузки блока. Для решения этой проблемы, должно бытьoutput.jsonpFunctionКонфигурация предоставляет пользовательское имя.

Webpack 5 отличается отpackage.json nameУникальное имя сборки автоматически выводится изoutput.uniqueNameзначение по умолчанию для .

Это значение используется для того, чтобы сделать уникальными все потенциально конфликтующие глобальные переменные.

Миграция: из-заpackage.jsonимеет уникальное имя, которое может бытьoutput.jsonpFunctionудалять.

6.5 Автоматически добавлять общедоступные пути

Webpack 5 автоматически определит, когда это возможноoutput.publicPath.

6.6 Типы машинописных текстов

Webpack 5 генерирует типы typescript из исходного кода и предоставляет их через пакеты npm.

мигрировать: удалить@types/webpack. Обновите ссылки, если имена различаются.

7. Оптимизация сборки

7.1 Вложенное встряхивание дерева

webpack теперь может отслеживать доступ к экспортированным вложенным свойствам. Это может улучшить реэкспорт пространств имен. Встряхивание дерева на объектах (очищает неиспользуемый экспорт и запутанный экспорт).

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

// module.js
export * as inner from './inner';
// 或 import * as inner from './inner'; export { inner };

// user.js
import * as module from './module';
console.log(module.inner.a);

В этом примере экспортируемый файл можно удалить в производственном режиме.b.

7.2 Внутреннее встряхивание модуля

webpack 4 не анализирует зависимости между экспортами и ссылками модулей. webpack 5 имеет новую опциюoptimization.innerGraph, включенный по умолчанию в производственном режиме, анализирует флаги в модулях, чтобы найти зависимости между экспортом и ссылками.

В таком модуле:

import { something } from './something';

function usingSomething() {
  return something;
}

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

Алгоритм внутреннего графа зависимостей обнаружитsomethingтолько при использованииtestИспользуется только при экспорте. Это позволяет помечать больше выходов как неиспользуемые и исключать больше кода из пакета кода.

когда установлено"sideEffects": false, другие модули могут быть опущены. В этом примере, когдаtestКогда экспорт не используется,./somethingЭто будет опущено.

Чтобы получить неиспользуемую экспортную информацию, вам нужно использоватьoptimization.unusedExports. Чтобы удалить модуль без побочных эффектов, вам нужно использоватьoptimization.sideEffects. Можно анализировать следующие теги:

  • объявление функции
  • объявление класса
  • 默认导出export defaultили определите переменную ниже:
    • функциональное выражение
    • выражение класса
    • последовательные выражения
    • /*#__PURE__*/выражение
    • локальная переменная
    • Введены привязки

Обратная связь: Если вы обнаружите, что чего-то не хватает в этом анализе, сообщите о проблеме, и мы рассмотрим ее добавление.

использоватьeval()Эта оптимизация будет исключена для модуля, поскольку проверенный код может ссылаться на любой тег в области видимости. Эта оптимизация также известна как анализ диапазона глубины.

7.3 CommonJs Tree Shaking

webpack раньше не делал экспорт в CommonJs иrequire()Экспорт анализа использования при вызове.

webpack 5 добавляет поддержку некоторых конструкций CommonJs, что позволяет исключить неиспользуемые экспорты CommonJs, а такжеrequire()Имя экспорта ссылки на трассировку в вызове.

Поддерживаются следующие конструкции:

  • exports|this|module.exports.xxx = ...
  • exports|this|module.exports = require("...") (reexport)
  • exports|this|module.exports.xxx = require("...").xxx (reexport)
  • Object.defineProperty(exports|this|module.exports, "xxx", ...)
  • require("abc").xxx
  • require("abc").xxx()
  • Импорт из ЕСМ
  • require()модуль ЕСМ
  • Отмеченные типы экспорта (специальная обработка нестрогого импорта ESM):
    • Object.defineProperty(exports|this|module.exports, "__esModule", { value: true|!0 })
    • exports|this|module.exports.__esModule = true|!0
  • Планы на будущее по поддержке большего количества конструкций

При обнаружении неанализируемого кода webpack сдастся и вообще не будет отслеживать экспорт этих модулей (по соображениям производительности).

7.4 Согласованность между разработкой и производством

Мы пытаемся найти хороший баланс между производительностью сборки режима разработки и избеганием проблем, возникающих только в режиме производства, улучшая сходство двух режимов.

В Webpack 5 оптимизация «sideEffects» включена по умолчанию в обоих режимах. В webpack 4 из-за"sideEffects"Плохо отмеченная, эта оптимизация вызвала некоторые ошибки, которые проявлялись только в рабочем режиме. Включение этой оптимизации во время разработки может ускорить и упростить поиск этих проблем.

Во многих случаях разработка и производство выполняются в разных операционных системах, а файловые системы имеют разную чувствительность к регистру, поэтому в webpack 5 добавлены некоторые странные предупреждения/ошибки.

7.5 Улучшенияtargetнастроить

В веб-пакете 4 «цель» находится в"web"а также"node"Грубый выбор между (и некоторыми другими). Webpack 5 дает вам больше возможностей.targetПараметры теперь влияют на большее количество вещей в сгенерированном коде, чем раньше, например, на метод загрузки блока кода, формат блока кода и т. д.externalsВключен ли он по умолчанию и т. д.

Кроме того, для некоторых из этих случаев в"web"а также"node"Выбор между слишком груб, и нам нужно больше информации. Поэтому мы разрешаем указывать минимальную версию, например."node10.13"и сделать вывод о дополнительных свойствах целевой среды.

Объединение нескольких целей с массивом теперь также разрешено, и webpack будет определять минимальные свойства для всех целей. Использование массивов также полезно при использовании чего-то вроде"web"или"node"Это не дает полной информации о цели (без номера версии). Например,["web", "es2020"]Объединяет эти две частичные цели.

иметь цель"browserslist", который будет использовать данные из библиотеки browserslist для определения свойств среды. Эта цель также используется по умолчанию, когда в проекте доступна конфигурация списка браузеров. Используется по умолчанию, когда конфигурация недоступна"web"Цель.

7.6 Разделение кодового блока и размер модуля

Теперь размер модуля выражается лучше, чем одно число. Сейчас есть разные размеры.

SplitChunksPlugin теперь знает, как обрабатывать эти разные размеры и использует их дляminSizeа такжеmaxSize. По умолчанию толькоjavascriptРазмеры обрабатываются, но теперь вы можете передавать несколько значений для управления ими:

module.exports = {
  optimization: {
    splitChunks: {
      minSize: {
        javascript: 30000,
        webassembly: 50000,
      },
    },
  },
};

Вы все еще можете использовать число для размера. В этом случае webpack будет автоматически использовать тип размера по умолчанию.

mini-css-extract-pluginиспользоватьcss/mini-extraв качестве типа размера, и этот тип размера автоматически добавляется к типу по умолчанию.

Существуют и другие оптимизации сборки, такие как отдельные улучшения среды выполнения, слияние модулей, общие улучшения Tree Shaking, улучшения отдельных сгенерированных кодов. Подробности см. в выпуске webpack 5.

8. Оптимизация производительности

8.1 Постоянный кеш

Теперь есть кеш файловой системы. Это необязательно и может быть включено со следующей конфигурацией:

module.exports = {
  cache: {
    // 1. 将缓存类型设置为文件系统
    type: 'filesystem',

    buildDependencies: {
      // 2. 将你的 config 添加为 buildDependency,以便在改变 config 时获得缓存无效
      config: [__filename],

      // 3. 如果你有其他的东西被构建依赖,你可以在这里添加它们
      // 注意,webpack、加载器和所有从你的配置中引用的模块都会被自动添加
    },
  },
};

важный:

По умолчанию webpack предполагает, что webpack находится вnode_modulesКаталоги изменяются только менеджером пакетов. правильноnode_modulesНапример, хэши и метки времени пропускаются. Из соображений производительности используются только имя и версия пакета. пока вы не укажетеresolve.symlinks: false, Симлинки (т.е.npm/yarn link) в порядке (его следует избегать в любом случае). Не редактируйте напрямуюnode_modulesфайл, если вы не используетеsnapshot.managedPaths: []убрать эту оптимизацию. При использовании Yarn PnP webpack предполагает, что кэш пряжи неизменяем (как это обычно и бывает). вы можете использоватьsnapshot.immutablePaths: []чтобы выйти из этой оптимизации.

Кэш будет храниться по умолчанию вnode_modules/.cache/webpack(при использовании node_modules) или.yarn/.cache/webpack(при использовании пряжи PnP). Когда все плагины правильно обрабатывают кеширование, вам никогда не придется удалять его вручную.

Многие внутренние плагины также используют постоянное кэширование. НапримерSourceMapDevToolPlugin(генерация исходной карты кэша) илиProgressPlugin(Количество кэш-модулей)

Постоянный кеш автоматически создает несколько файлов кеша в зависимости от использования, чтобы оптимизировать доступ для чтения и записи к кешу.

По умолчанию временные метки будут использоваться для моментальных снимков в режиме разработки, а хэши файлов будут использоваться в рабочем режиме. Хэши файлов также допускают постоянное кэширование в CI.

8.2 Простой компилятора и завершение работы

Компилятор теперь должен быть закрыт после использования. Теперь компилятор входит в состояние ожидания и выходит из него, и у него есть ловушки для этих состояний. Плагины могут использовать эти хуки для неважной работы. (т. е. постоянный кеш, медленно сохраняющий кеш на диск). При выключении компилятора вся оставшаяся работа должна быть выполнена как можно быстрее. Обратный вызов отмечает завершение выключения.

Плагины и их соответствующие авторы должны предвидеть, что некоторые пользователи могут забыть закрыть компилятор. Таким образом, вся работа в конечном итоге также должна выполняться в состоянии простоя. Следует предотвратить завершение процесса во время выполнения работы.

webpack()использование вызывается автоматически при передаче обратного вызоваclose.

Миграция: при использовании Node.js API обязательно вызывайте его после завершения работы.Compiler.close.

8.3 Генерация файлов

Раньше webpack всегда выдавал все выходные файлы при первой сборке, но пропускал запись неизмененных файлов при инкрементных (наблюдаемых) сборках. Предполагая, что ничто другое не изменяет выходной файл во время работы веб-пакета.

С добавлением постоянного кэширования должен быть опыт прослушивания даже при перезапуске процесса веб-пакета, но это слишком сильное предположение, чтобы предположить, что ничто другое не изменяет выходной каталог, даже когда веб-пакет не запущен.

Таким образом, webpack теперь будет проверять существующие файлы в выходном каталоге и сравнивать их содержимое с выходным файлом в памяти. Он записывает в файл только тогда, когда он был изменен. Это происходит только при первой сборке. Любая инкрементная сборка будет записывать файлы по мере создания новых ресурсов в запущенном процессе веб-пакета.

Мы предполагаем, что веб-пакет и плагины будут генерировать новые активы только при изменении содержимого. Кэширование следует использовать, чтобы гарантировать, что новые активы не будут генерироваться, когда входные данные одинаковы. Несоблюдение этого совета приведет к снижению производительности.

отмечен как[不可变]Файл (включая хэш содержимого) никогда не будет записан, если файл с таким именем уже существует. Мы предполагаем, что при изменении содержимого файла меняется хэш содержимого. В целом это верно, но не всегда верно во время разработки веб-пакетов или плагинов.

9. Критические изменения: давно нерешенные проблемы

9.1 Разделение кода для однофайловых объектов

Цели, которые позволяют запускать только один файл (например, node, WebWorker, electronic main), теперь поддерживают автоматическую загрузку во время выполнения зависимых фрагментов кода, необходимых для начальной загрузки.

Это позволяет этим целям использоватьchunks: "all"а такжеoptimization.runtimeChunk.

Обратите внимание, что если загрузка блока кода цели является асинхронной, это также делает асинхронной начальную оценку. когда используешьoutput.library, это может быть проблемой, так как экспортируемое значение теперь является обещанием.

9.2 Обновлен парсер

enhanced-resolveОбновлено до v5 со следующими улучшениями:

  • Отслеживайте дополнительные зависимости, например отсутствующие файлы.
  • Псевдонимы могут иметь несколько вариантов
  • теперь может быть псевдонимом какfalse.
  • служба поддержкиexportsа такжеimportsполя и др.
  • улучшение производительности

9.3 Блоки кода без JS

Блоки, не содержащие JS-код, больше не будут генерировать JS-файлы. Это позволяет использовать блоки кода, содержащие только CSS.

10. Значительные изменения: планы на будущее

10.1 Экспериментальные характеристики

В вебпаке 5 появился новыйexperimentsПараметр конфигурации, позволяющий включить экспериментальные функции. Это дает понять, какие функции включены/используются.

Хотя веб-пакет следует семантическому управлению версиями, он делает исключения для экспериментальных функций. Экспериментальные функции могут содержать критические изменения в второстепенных версиях webpack. Когда это произойдет, мы добавим явное примечание в журнал изменений. Это позволит нам быстрее итерировать экспериментальные функции, а также позволит нам дольше оставаться на основных выпусках для стабильных функций.

Следующие экспериментальные функции будут выпущены вместе с webpack 5.

  • Старая поддержка WebAssembly, как и в webpack 4 (experiments.syncWebAssembly)
  • согласно собновленная спецификация(experiments.asyncWebAssembly), добавлена ​​поддержка WebAssembly.
    • Это делает модуль WebAssembly асинхронным модулем.
  • Подождите сверхуПредложение третьего этапа (experiments.topLevelAwait)
    • использовать на высшем уровнеawaitСделайте модуль асинхронным.
  • Генерировать пакеты кода в виде модулей (experiments.outputModule)
    • Это удаляет оболочку IIFE из пакета кода, применяет строгий режим через<script type="module">Делайте ленивую загрузку и минимизируйте сжатие в модульном режиме.

Обратите внимание, что это также означает, что поддержка WebAssembly теперь отключена по умолчанию.

10.2 Минимальная версия Node.js

Минимальная поддерживаемая версия Node.js увеличена с 6 до 10.13.0 (LTS).

Миграция: обновите Node.js до последней версии.

11. Основные изменения внутренней архитектуры

Эта часть в основном предназначена для тех, кто хочет внести свой вклад в ядро ​​веб-пакета, а также для разработчиков загрузчиков и плагинов, которым необходимо уделить пристальное внимание. Если вы просто используете webpack, вы можете игнорировать эту часть. Содержание очень большое и сложное для понимания.

Давайте представим некоторые из наиболее важных изменений внутренней архитектуры.

11.1 Новый порядок запуска плагина

Плагины в webpack 5 теперь применяют настройки по умолчанию.Добудет применяться. Это позволяет плагинам применять свои собственные настройки по умолчанию или в качестве предустановок конфигурации. Но это также критическое изменение, так как плагины не могут полагаться на настройку значений конфигурации при применении.

Миграции: доступ к конфигурации только в хуках плагинов. Или лучше вообще не обращаться к конфигу и получать опции через конструктор.

11.2 Запуск модуля

Большая часть кода среды выполнения была перемещена в так называемые «модули среды выполнения». Эти специальные модули отвечают за добавление кода времени выполнения. Их можно добавить в любой блок, но в настоящее время они всегда добавляются в блоки времени выполнения. «Требования к среде выполнения» определяют, какие модули среды выполнения (или основные части среды выполнения) добавляются в пакет кода. Это гарантирует, что в пакет кода будет добавлен только используемый код среды выполнения. В будущем модули среды выполнения также могут быть добавлены к блокам по запросу для загрузки кода среды выполнения при необходимости.

В большинстве случаев ядру разрешено встраивать модуль ввода при запуске кода вместо использования__webpack_require__назвать это. Если в пакете кода нет других модулей, вам вообще не нужно использовать__webpack_require__. Это хорошо работает при слиянии модулей, т. е. несколько модулей объединяются в один модуль. В лучшем случае исполняемый код вообще не требуется.

Миграция: если вы вставляете код среды выполнения в свой плагин в среду выполнения веб-пакета, рассмотрите возможность использования вместо этого RuntimeModules.

11.3 Сериализация

Мы добавили механизм сериализации, позволяющий сериализовать сложные объекты в webpack. Он имеет необязательную семантику, поэтому те классы, которые должны быть сериализованы, должны быть явно помечены (и реализована их сериализация). Большинство модулей, все зависимости и некоторые баги уже делают это.

Миграции: при использовании пользовательских модулей или зависимостей рекомендуется реализовать их как сериализуемые, чтобы воспользоваться преимуществами постоянного кэширования.

11.4 Плагины для кеширования

Добавлен интерфейс плагина сCacheДобрый. Этот класс можно использовать для кэшей записи и чтения. В зависимости от конфигурации различные плагины могут добавлять функциональность в кеш.MemoryCachePluginДобавлена ​​функция кэширования памяти.FileCachePluginДобавлено постоянное (файловая система) кэширование.FileCachePluginЭлементы кэша сохраняются на диске и восстанавливаются с него с помощью механизма сериализации.

11.5 Обновление плагина Tapable

Слой совместимости для плагина webpack 3 был удален. Он устарел в webpack 4. Некоторые из менее используемых подключаемых API были удалены или объявлены устаревшими.

Миграция: используйте новый Tapable API.

11.6 Устаревший шаблон Main/Chunk/ModuleTemplate

Шаблоны упаковки были переработаны. MainTemplate/ChunkTemplate/ModuleTemplate устарели, теперь за шаблонизацию JS отвечает JavascriptModulesPlugin.

До этого рефакторинга вывод JS обрабатывался Main/ChunkTemplate, а другой вывод (например, WASM, CSS) обрабатывался плагинами. Похоже, JS — первоклассный гражданин, а остальные результаты — второсортные. Рефакторинг изменил это, весь вывод обрабатывается их плагином.

Некоторые шаблоны все еще можно взломать. Хуки теперь находятся в JavascriptModulesPlugin вместо Main/ChunkTemplate. (Да, плагины также могут иметь хуки, которые я называю хуками добавления.) Существует уровень совместимости, поэтому Main/Chunk/ModuleTemplate все еще существует, но просто делегирует вызов касания в новое местоположение хука.

Миграция: следуйте советам в сообщении об устаревании. В основном крючки, указывающие на разные места.

11.7 Новая конфигурация файла ввода

В webpack 5, помимо строк и массивов строк, входные файлы также можно настраивать с помощью дескрипторов, таких как:

module.exports = {
  entry: {
    catalog: {
      import: './catalog.js',
    },
  },
};

Кроме того, вы также можете определить имя выходного файла, которое ранее прошло черезoutput.filenameОпределенный:

module.exports = {
  entry: {
    about: { import: './about.js', filename: 'pages/[name][ext]' },
  },
};

Кроме того, конфигурация входного файла добавляет определение зависимости файла, тип формата сгенерированной библиотеки классов (commonjs или amd), а также может установить имя среды выполнения и метод загрузки блоков кода. к полной записи о выпуске.

11.8 Сортировка и идентификаторы

webpack используется для упорядочивания модулей и фрагментов определенным образом на этапе компиляции, присваивая идентификаторы в возрастающей манере. Это больше не так. Порядок больше не будет использоваться для генерации идентификатора, вместо этого генерация идентификатора полностью контролируется в плагине. Хуки для оптимизации порядка модулей и блоков кода были удалены.

Миграция: на этапе компиляции вы больше не можете полагаться на порядок модулей и блоков кода.

11.9 От массива к набору (набору)

  • Compilation.modules теперь является коллекцией
  • Compilation.chunks теперь является коллекцией
  • Chunk.files теперь является коллекцией

Уровень адаптации существует, но выводит устаревшее предупреждение.

Миграция: используйте методы коллекции вместо методов массива.

11.10 Файловая система и изменения информации

В webpack 5 нужно использоватьCompilation.fileSystemInfoзаменятьfile/contextTimestamps, получить информацию о временной метке файла, а другой — добавитьCompiler.modifiedFilesчтобы упростить ссылку на измененный файл.

Кроме того, новыйcompiler.inputFileSystemа такжеcompiler.outputFileSystemновый API дляcompiler.intermediateFileSystem, для всех операций fs, которые не считаются вводом или выводом, например запись записей, кэширование или профилирование вывода.

11.11 Горячая замена модуля

Среда выполнения HMR преобразована в модуль среды выполнения.HotUpdateChunkTemplateбыл объединен вChunkTemplateсередина. ChunkTemplates и плагины также должны обрабатыватьHotUpdateChunk.

Часть javascript среды выполнения HMR была отделена от основной среды выполнения HMR. Другие типы модулей теперь также могут обрабатывать HMR по-своему. В будущем это позволит HMR обрабатывать такие модули, как mini-css-extract-plugin или WASM.

Миграция: это новая функция, и миграция не требуется.

import.meta.webpackHotопубликовано сmodule.hotтот же API. Конечно, его можно использовать в модулях ESM (.mjs, тип: «модуль» в package.json), к которым эти модули не имеют доступа.module.

11.12 Очередь работ

WebPack обрабатывается функцией вызова функции, есть еще однаsemaphoreВозможность ограничения параллелизма.Compilation.semaphoreЭто было удалено и теперь может обрабатываться с использованием асинхронных очередей с отдельными очередями для каждого шага:

  • Compilation.factorizeQueue: вызывает фабрику модулей для набора зависимостей.
  • Compilation.addModuleQueue: добавить модуль в очередь на компиляцию (модули можно восстановить с помощью кеша)
  • Compilation.buildQueue: построить модуль при необходимости (можно сохранить модуль в кэше)
  • Compilation.rebuildQueue: при ручном запуске модуль будет перестроен
  • Compilation.processDependenciesQueue: Обработка зависимостей модулей.

В этих очередях будут хуки для прослушивания и перехвата рабочих процессов. В будущем несколько компиляторов будут работать одновременно, и работу по компиляции можно будет организовать, перехватывая эти очереди.

Миграция: это новая функция, и миграция не требуется.

11.13 Диаграммы модулей и блоков

webpack используется для хранения разрешенных модулей в зависимостях и импортированных модулей в кусках. Но теперь это изменилось. Вся информация о том, как модули связаны в графе модулей, теперь хранится в классе ModulGraph. Вся информация о том, как модули связаны с чанками, теперь хранится в классе ChunkGraph. Информация, которая зависит от графа фрагментов, также хранится в связанном классе.

Вот несколько примеров модулей, информация о которых была перемещена:

  • Module connections -> ModuleGraph
  • Module issuer -> ModuleGraph
  • Module optimization bailout -> ModuleGraph (TODO: check if it should ChunkGraph instead)

При восстановлении модуля из кеша webpack отключит модуль от графа. В этом больше нет необходимости. Модуль не хранит никакой информации о графе и технически может использоваться в нескольких графах. Это упрощает кэширование. Большинство этих изменений имеют уровень адаптации, который выводит предупреждение об устаревании при использовании.

Миграция: используйте новый API для ModuleGraph и ChunkGraph.

11.14 Типы источников модулей

Теперь модули должны проходитьModule.getSourceTypes()для определения типов источников, которые они поддерживают. В соответствии с этим разные плагины вызывают с этими типамиsource(). Для исходного типаjavascriptизJavascriptModulesPluginвстроит исходный код в бандл. Тип источникаwebassemblyизWebAssemblyModulesPluginВыдаст wasm-файл. В то же время поддерживаются и пользовательские типы источников, например, mini-css-extract-plugin будет использовать типы источников какstylesheetВставьте исходный код в файл css.

Между типами модулей и типами источников нет никакой связи. даже если тип модуляjson, вы также можете использовать исходный тип какjavascriptи тип модуляwebassembly/experimentalизjavascriptа такжеwebassembly.

Миграция: пользовательские модули должны реализовать эти новые методы интерфейса.

11.15 Новый наблюдатель

Наблюдатели, используемые webpack, подверглись рефакторингу. Это былоchokidarи родные зависимостиfsevents(Только на OSX). Теперь он основан только на Node.js.fs. Это означает, что в webpack больше нет нативных зависимостей.

Он также захватывает больше информации о файловой системе во время прослушивания. В настоящее время он также может фиксировать mtime и отслеживать время событий, а также информацию об отсутствующих файлах. с этой целью,WatchFileSystemВ API внесены небольшие изменения. Наряду с модификацией мы также преобразовали массивы в наборы и объекты в карты.

11.16 SizeOnlySource after emit

вебпак теперь используетSizeOnlySourceзаменятьCompilation.assetsИсходники, чтобы уменьшить объем памяти.

11.17 ExportsInfo

Переработан способ хранения информации об экспорте модуля. ModuleGraph теперь для каждогоModuleпредоставилExportsInfo, в котором хранится информация о каждом экспорте. Если модуль используется только в качестве побочного эффекта, он также хранит информацию о неизвестных экспортах,

Для каждого экспорта сохраняется следующая информация:

  • Использовать ли экспорт — не уверен. (видетьoptimization.usedExports)
  • Доступен ли экспорт? (видетьoptimization.providedExports)
  • Можно ли переименовать имя экспорта?
  • Если экспорт был переименован, новое имя. (видетьoptimization.mangleExports)
  • Вложенная информация ExportsInfo, которая сама является объектом, если экспорт является объектом с дополнительной информацией.
    • Для повторного экспорта объектов пространства имен:import * as X from "..."; export { X };
    • Используется для представления структур в модуле JSON.

11.18 Фаза генерации кода

Генерация скомпилированного кода функционирует как отдельная фаза компиляции. это больше не скрытоModule.source()а такжеModule.getRuntimeRequirements()в операции. Это должно упростить процесс. Он также работает, сообщая о ходе выполнения этой фазы. И делает генерацию кода более заметной при профилировании.

мигрировать:Module.source()а такжеModule.getRuntimeRequirements()Устарело. использоватьModule.codeGeneration()заменять.

11.19 Справочник по зависимостям

Раньше в webpack был один метод и тип для представления ссылок на зависимости (Compilation.getDependencyReferenceвернетDependencyReference) Этот тип используется для представления всей информации о ссылке, такой как модуль, на который ссылаются, какие экспорты были введены, и если это слабая ссылка, вам необходимо подписаться на некоторую связанную информацию. Собирать всю эту информацию вместе дорого и часто (каждый раз, когда кому-то нужна информация).

В webpack5 эта часть кодовой базы подверглась рефакторингу и разделению методов.

  • Ссылочные модули можно прочитать из ModuleGraphConnection.
  • Введены экспортные имена, доступ к которым можно получить черезDependency.getReferencedExports()Получать
  • DependencyБудет класс наweakфлаг
  • сортировать только сHarmonyImportDependenciesсвязанные, черезsourceOrderприобретение собственности

11.20 Presentational Dependencies

ЭтоNormalModulesНовый тип зависимостей для: презентационных зависимостей.

Эти зависимости используются только на этапе генерации кода, но не в процессе построения графа модуля. Поэтому они никогда не могут ссылаться на модули или влиять на экспорт/импорт.

Эти зависимости дешевы в обработке, и веб-пакет будет использовать их, когда это возможно.

11.21 Устаревшие загрузчики

  • null-loader

    Устарело. использовать

    module.exports = {
      resolve: {
        alias: {
          xyz$: false,
        },
      },
    };
    

    или используйте абсолютный путь

    module.exports = {
      resolve: {
        alias: {
          [path.resolve(__dirname, '....')]: false,
        },
      },
    };
    

12. Резюме

Большая часть работы webpack 5 вращается вокруг оптимизации, удаления устаревшего контента в 4, добавления долгосрочного кэширования, оптимизации ядра и т. д. В этой статье выделены только ключевые моменты, которые должен объяснить каждый.Чтобы узнать о конкретных изменениях, обратитесь к официальной документации.

13. Следите за нами

Мы предоставим вам самую свежую передовую информацию.