ожидать
Я надеюсь, что после прочтения этой статьи, когда вы смотрите на конфигурацию Webpack, вы сможете сформировать в уме процесс генерации чанка.
Chunk
Чанк отличается от таких понятий, как вход, выход и модуль. Они соответствуют полю в объекте конфигурации Webpack. У чанка нет отдельного поля конфигурации, но это слово появляется в CommonsChunkPlugin (до Webpack3), оптимизация.splitChunks (после Webpack4), как в названии.
Чанк — это концепция, которую мы должны понять, чтобы понять Webpack.
Чанк — это блок кода в Webpack. К какому типу блока кода он относится?
Chunk VS Module
Module
Прежде всего, для модулей Webpack можно рассматривать как упаковщик модулей.Любой файл, который мы пишем, является модулем для Webpack. Поэтому в конфигурационном файле Webpack есть поле module, а под модулем есть поле rules, под правилами находятся правила обработки модулей, какой тип модуля настраивается, какой тип загрузчика обрабатывается.
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: "style-loader"
}, {
loader: "css-loader"
}
]
},
...
]
},
Chunk
Чанк — это набор модулей в процессе упаковки Webpack. Мы знаем, что упаковка Webpack начинается с входного файла, который также можно назвать входным модулем.Входной модуль ссылается на этот другой модуль, а модуль ссылается на модуль. Webpack упаковывает модули один за другим через ссылочное отношение, и эти модули образуют фрагмент.
Если у нас есть несколько входных файлов, может быть сгенерировано несколько путей упаковки, и один путь будет формировать фрагмент. Есть два способа генерировать чанки при выходе из входа, которые будут представлены ниже.
Chunk VS Bundle
Обычно мы путаем эти два понятия, думая, что Chunk — это Bundle, а Bundle — это один или несколько упакованных файлов, которые мы в итоге выводим. В самом деле, в большинстве случаев Чанк создаст Бандл. Но иногда это не совсем однозначная связь, например, мы настраиваем devtool как «исходную карту». Тогда есть только один входной файл, и никакое разделение кода не настроено:
// webpack配置
entry: {
main: __dirname + "/app/main.js",
},
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
},
devtool: 'source-map',
Такая конфигурация будет генерировать один чанк, но два пакета, как показано ниже.
Обратите внимание, что в столбце «Имена фрагментов» есть только один фрагмент, такой как основной.Глядя на столбец «Актив», создаются два пакета и файл .map.В этом разница между Chunk и Bundle, Chunk — это блок кода в процессе, Bundle — это блок кода результата.
Проверьте исходный код Webpack и найдите Chunk.js, нажмите, чтобы увидеть:
/**
* A Chunk is a unit of encapsulation for Modules.
* Chunks are "rendered" into bundles that get emitted when the build completes.
*/
class Chunk {
}
В нем есть класс Chunk, а это значит, что класс Webpack будет генерировать объекты Chunk при запуске, а также может доказать, что Chunk — это блок кода в процессе.
Два комментария выше класса Chunk: Chunk — это единица инкапсуляции некоторых модулей. Чанк представляется в виде пакета после завершения сборки.
Три способа сгенерировать чанк
- Вход
- Загружать модули асинхронно
- разделение кода
запись генерирует чанк
Существует три способа настройки входа:
передать строку
entry: './src/js/main.js',
Эта ситуация создаст только Чанк. (Здесь упоминается только влияние записи на чанк, а сегментация кода не задействована)
передать массив
entry: ['./src/js/main.js','./src/js/other.js'],
В этом случае будет сгенерирован только один чанк. В конечном итоге Webpack упакует исходный код из массива в Bundle, потому что генерируется только один Chunk.
передать объект
entry: {
main: './src/js/main.js',
other: './src/js/other.js'
},
output: {
// path: __dirname + "/public",
// filename:'bundle.js'
// 以上2行会报错
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
}
Поле в объекте будет генерировать фрагмент, поэтому имя файла в выходных данных напрямую записывает имя, и будет сообщено об ошибке. Из-за приведенной выше конфигурации генерируются два чанка, и в конечном итоге будут сгенерированы два пакета.Одного имени определенно недостаточно. Вам нужно использовать переменную [name], чтобы использовать имя поля под записью в качестве имени сгенерированных пакетов.
Ключ записи также используется в качестве имени соответствующего чанка.Существует два способа передачи строки и массива.Без ключа сгенерированному чанку по умолчанию будет присвоено основное имя.
Генерировать чанки асинхронно
В дополнение к входному файлу, влияющему на чанки, асинхронно загружаемые модули также должны генерировать чанки.
{
entry: {
"index": "pages/index.jsx"
},
output: {
filename: "[name].min.js",
chunkFilename: "[name].min.js"
}
}
const myModel = r => require.ensure([], () => r(require('./myVue.vue')), 'myModel')
Вот где поле chunkFilename пригодится для именования чанка, загруженного асинхронно.
Разделение кода производит куски
Давайте проанализируем, следующий код сгенерирует несколько чанков, в которых файл main.js и файл two.js ссылаются на один и тот же файл Greeter.js. React используется в main.js.
module.exports = {
entry: {
main: __dirname + "/app/main.js",
other: __dirname + "/app/two.js",
},
output: {
path: __dirname + "/public",//打包后的文件存放的地方
filename: "[name].js", //打包后输出文件的文件名
chunkFilename: '[name].js',
},
optimization: {
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
commons: {
chunks: "initial",
minChunks: 2,
maxInitialRequests: 5, // The default limit is too small to showcase the effect
minSize: 0 // This is example is too small to create commons chunks
},
vendor: {
test: /node_modules/,
chunks: "initial",
name: "vendor",
priority: 10,
enforce: true
}
},
}
}
}
Ответ — 5, по одному для каждой из двух записей, runtimeChunk: «single» будет отделять код, требуемый Webpack при работе на стороне браузера, в файл, конфигурация в commons сгенерирует Chunk, а конфигурация в vendor будет Сгенерируйте чанк. Как показано ниже.
заключительные замечания
Вот и все для сегодняшнего исследования.
Глядя на конфигурацию Webpack, вы можете определить, сколько чанков может быть сгенерировано такой конфигурацией.Даже если Webpack является записью, позже будет намного проще понять его другие концепции.