Может кто-нибудь объяснить Webpack CommonsChunkPlugin
Я получаю общий смысл, что CommonsChunkPlugin
просматривает все точки входа, проверяет, есть ли между ними общие пакеты/зависимости и разделяет их на свой собственный пакет.
Итак, допустим, у меня есть следующая конфигурация:
...
enrty : {
entry1 : 'entry1.js', //which has 'jquery' as a dependency
entry2 : 'entry2.js', //which has 'jquery as a dependency
vendors : [
'jquery',
'some_jquery_plugin' //which has 'jquery' as a dependency
]
},
output: {
path: PATHS.build,
filename: '[name].bundle.js'
}
...
Если я свяжусь без использования CommonsChunkPlugin
В итоге у меня появятся 3 новых файла пакета:
-
entry1.bundle.js
, который содержит полный код из entry1.js
и jquery
и содержит собственную среду выполнения
-
entry2.bundle.js
, который содержит полный код из entry2.js
и jquery
и содержит собственную среду выполнения
-
vendors.bundle.js
, который содержит полный код из jquery
и some_jquery_plugin
и содержит свое собственное время выполнения
Это, очевидно, плохо, потому что я потенциально буду загружать jquery
3 раза на страницу, поэтому мы этого не хотим.
Если я свяжусь с помощью CommonsChunkPlugin
В зависимости от того, какие аргументы передаются на CommonsChunkPlugin
, произойдет следующее:
-
CASE 1: Если я пройду { name : 'commons' }
, у меня появятся следующие файлы пакетов:
-
entry1.bundle.js
, который содержит полный код из entry1.js
, требование для jquery
и не содержит время выполнения
-
entry2.bundle.js
, который содержит полный код из entry2.js
, требование для jquery
и не содержит время выполнения
-
vendors.bundle.js
, который содержит полный код из some_jquery_plugin
, требование для jquery
и не содержит время выполнения
-
commons.bundle.js
, который содержит полный код из jquery
и содержит время выполнения
Таким образом, мы получим несколько небольших пакетов в целом, а время выполнения содержится в пакете commons
. Довольно нормально, но не идеально.
-
CASE 2: Если я пройду { name : 'vendors' }
, у меня появятся следующие файлы пакетов:
-
entry1.bundle.js
, который содержит полный код из entry1.js
, требование для jquery
и не содержит время выполнения
-
entry2.bundle.js
, который содержит полный код из entry2.js
, требование для jquery
и не содержит время выполнения
-
vendors.bundle.js
, который содержит полный код из jquery
и some_jquery_plugin
и содержит время выполнения.
Таким образом, мы снова получаем несколько небольших пакетов, но среда выполнения теперь содержится в пакете vendors
. Это немного хуже, чем в предыдущем случае, поскольку среда выполнения теперь находится в пакете vendors
.
-
CASE 3: Если я пройду { names : ['vendors', 'manifest'] }
, у меня появятся следующие файлы пакетов:
-
entry1.bundle.js
, который содержит полный код из entry1.js
, требование для jquery
и не содержит время выполнения
-
entry2.bundle.js
, который содержит полный код из entry2.js
, требование для jquery
и не содержит время выполнения
-
vendors.bundle.js
, который содержит полный код из jquery
и some_jquery_plugin
и не содержит среды выполнения
-
manifest.bundle.js
, который содержит требования для каждого другого пакета и содержит время выполнения
Таким образом, мы заканчиваем небольшими пакетами в целом, а время выполнения содержится в пакете manifest
. Это идеальный случай.
Что я не понимаю/Я не уверен, что понимаю
-
В CASE 2 почему мы закончили с пакетом vendors
, содержащим как общий код (jquery
), так и все, что осталось от записи vendors
(some_jquery_plugin
)? По моему мнению, что CommonsChunkPlugin
здесь заключалось в том, что он собрал общий код (jquery
), и поскольку мы вынудили его вывести его в пакет vendors
, он вроде как "объединил" общий код в vendors
bundle (который теперь содержит только код из some_jquery_plugin
). Пожалуйста, подтвердите или объясните.
-
В CASE 3 Я не понимаю, что произошло, когда мы передали { names : ['vendors', 'manifest'] }
плагину. Почему/как пакет vendors
сохранялся неповрежденным, содержащим как jquery
, так и some_jquery_plugin
, когда jquery
явно является общей зависимостью, и почему был создан сгенерированный файл manifest.bundle.js
так, как он был создан (требующий всех другие пакеты и содержащие время выполнения)?
Ответы
Ответ 1
Вот как работает CommonsChunkPlugin
.
Общий кусок "получает" модули, разделяемые несколькими блоками ввода.
Хороший пример сложной конфигурации можно найти в репозитории Webpack.
CommonsChunkPlugin
выполняется во время фазы оптимизации Webpack, что означает, что он работает в памяти, незадолго до того, как куски запечатаны и записаны на диск.
Когда определено несколько общих кусков, они обрабатываются по порядку. В вашем случае 3 это похоже на запуск плагина дважды. Но учтите, что CommonsChunkPlugin
может иметь более сложную конфигурацию (minSize, minChunks и т.д.), Которая влияет на перемещение модулей.
CASE 1:
- Есть 3
entry
куска (entry1
, entry2
и vendors
).
- Конфигурация устанавливает блок
commons
как общий фрагмент.
- Плагин обрабатывает общий фрагмент
commons
(так как кусок не существует, он создается):
- Он собирает модули, которые используются более одного раза в других фрагментах:
entry1
, entry2
и vendors
используют jquery
, поэтому модуль удаляется из этих фрагментов и добавляется в блок commons
.
- Блок
commons
помечен как фрагмент entry
, в то время как фрагменты entry1
, entry2
и vendors
не отмечены как entry
.
- Наконец, поскольку блок
commons
- это блок entry
, он содержит модуль времени выполнения и jquery
.
CASE 2:
- Есть 3
entry
куска (entry1
, entry2
и vendors
).
- Конфигурация устанавливает блок
vendors
как общий фрагмент.
- Плагин обрабатывает общий кусок
vendors
:
- Он собирает модули, которые используются более одного раза в других фрагментах:
entry1
и entry2
используют jquery
, поэтому модуль удаляется из этих фрагментов (обратите внимание, что он не добавлен в блок vendors
потому что кусок vendors
уже содержит его).
- Блок
vendors
помечен как фрагмент entry
, в то время как фрагменты entry1
и entry2
не отмечены как entry
.
- Наконец, поскольку блок
vendors
является блоком entry
, он содержит модули времени выполнения и jquery
/jquery_plugin
.
CASE 3:
- Есть 3
entry
куска (entry1
, entry2
и vendors
).
- Конфигурация устанавливает кусок
vendors
и фрагмент manifest
как обычные куски.
- Плагин создает кусок
manifest
, поскольку он не существует.
- Плагин обрабатывает общий кусок
vendors
:
- Он собирает модули, которые используются более одного раза в других фрагментах:
entry1
и entry2
используют jquery
, поэтому модуль удаляется из этих фрагментов (обратите внимание, что он не добавлен в блок vendors
потому что кусок vendors
уже содержит его).
- Блок
vendors
помечен как фрагмент entry
, в то время как фрагменты entry1
и entry2
не отмечены как entry
.
- Плагин обрабатывает общий кусок
manifest
(так как кусок не существует, он создается):
- Он собирает модули, которые используются более одного раза в других кусках: поскольку нет модулей, используемых более одного раза, модуль не перемещается.
- Блок
manifest
помечен как entry
chunk, а entry1
, entry2
и vendors
не отмечены как entry
.
- Наконец, поскольку кусок
manifest
представляет собой фрагмент entry
, он содержит среду выполнения.
Надеюсь, что это поможет.