разделение кода в webpack 4 и внедрение var - PullRequest
0 голосов
/ 27 апреля 2018

Я пытаюсь добиться разделения кода при работе с webpack 4 (предыдущий конфиг с webpack 3 работал правильно)

Я создал хранилище, чтобы легко воспроизвести мою проблему: https://github.com/iamdey/RD-webpack4-code-split

Обычно я зацикливаюсь на следующей ошибке, потому что я хочу разделить код и babel-polyfill в комплекте поставщика:

ReferenceError: регенераторRuntime не определен

Конфиг

Вот мой конфиг веб-пакета:

{
  entry: {
    app: ['./src/index.js'],
    vendor: [
      'babel-polyfill',
      'moment',
    ],
  },
  output: {
    filename: '[name].[chunkhash].js',
    chunkFilename: '[name].[chunkhash].js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      chunksSortMode: (chunk1, chunk2) => {
        // make sure babel-polyfill in vendors is loaded before app
        const order = ['manifest', 'vendor', 'app'];
        const order1 = order.indexOf(chunk1.names[0]);
        const order2 = order.indexOf(chunk2.names[0]);

        return order1 - order2;
      },
    }),
  ],
  optimization: {
    runtimeChunk: {
      name: 'manifest',
    },
    splitChunks: {
      cacheGroups: {
        vendor: {
          chunks: 'initial',
          name: 'vendor',
          test: 'vendor',
          enforce: true,
        },
      },
    },
  }
}

Проблема

При отладке мы видим, что вендор загружается сразу после манифеста и, наконец, приложения. Но приложение выполняется до поставщика.

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

Что делать?

Вот варианты, которые у меня есть:

  • положить polyfill в комплект приложения вместо комплекта поставщика: я не хочу этого
  • оставьте веб-пакет, делайте код самостоятельно: я не хочу этого, потому что в реальном мире я хочу очень долгое кэширование даже между выпусками вендора и поддерживать приложение как можно меньшим
  • Конфигурация веб-пакета неверна: Скажите, пожалуйста:)
  • Это, вероятно, ошибка: Круто, я открою проблему как можно скорее

1 Ответ

0 голосов
/ 27 апреля 2018

Давайте начнем с загрузки и выполнения полизаполнения как части каждой точки входа (как видно из документа babel-polyfill ), чтобы он выглядел следующим образом

app: ['babel-polyfill', './src/index.js'],
vendor: ['moment'],

Вот вывод после npm run start2:

                           Asset       Size    Chunks             Chunk Names
     app.53452b510a24e3c11f03.js    419 KiB       app  [emitted]  app
manifest.16093f9bf9de1cb39c92.js   5.31 KiB  manifest  [emitted]  manifest
  vendor.e3f405ffdcf40fa83b3a.js    558 KiB    vendor  [emitted]  vendor

Что я понимаю, так это настройка babel-polyfill в entry.app, которая сообщает веб-пакету, что приложение требует полифилл. И пакет, определенный в vendor, сообщает плагину splitChunk, какие пакеты нужно объединить в группу кеша.

Учитывая моё понимание от split-chunks-plugin doc

Опция теста определяет, какие модули выбираются этой группой кеша. Отказ от этого выбирает все модули.

Таким образом, удаление опции test из cacheGroup приведет к тому, что весь код будет перемещен в комплект поставщика.

Зная, что у нас есть 2 решения.

1 / Использование обходного пути и дубликата загруженного скрипта

{
  entry: {
    app: [
      'babel-polyfill',
      './src/index.js',
    ],
    vendor: [
      'babel-polyfill',
      'moment',
    ],
  },
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendors: {
          chunks: 'initial',
          name: 'vendor',
          test: 'vendor',
          enforce: true,
        },
      },
    },
    runtimeChunk: {
      name: 'manifest',
    },
  },
}

Поэтому мы сообщаем веб-пакету, что приложению требуется babel-polyfill, и splitChunks, что babel-polyfill и moment являются поставщиками для использования в группе кэша.

2 / Использовать импорт вместо загрузчика скриптов

В index.js

import 'babel-polyfill';
import moment from 'moment';

// ...

webpack.config.js

{
  entry: {
    app: [
      './src/index.js',
    ],
    vendor: [
      'babel-polyfill',
      'moment',
    ],
  },
  // ...

Это гарантирует, что приложение заполняет polyfill.

Надеюсь, это поможет!

...