Webpack понимает чанки

Webpack

ожидать

Я надеюсь, что после прочтения этой статьи, когда вы смотрите на конфигурацию 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',

Такая конфигурация будет генерировать один чанк, но два пакета, как показано ниже.

image
Обратите внимание, что в столбце «Имена фрагментов» есть только один фрагмент, такой как основной.Глядя на столбец «Актив», создаются два пакета и файл .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 — это единица инкапсуляции некоторых модулей. Чанк представляется в виде пакета после завершения сборки.

Три способа сгенерировать чанк

  1. Вход
  2. Загружать модули асинхронно
  3. разделение кода

запись генерирует чанк

Существует три способа настройки входа:

передать строку

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 будет Сгенерируйте чанк. Как показано ниже.

image

заключительные замечания

Вот и все для сегодняшнего исследования.

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