Разделение кода webpack 4 и внедрение var

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

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

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

ReferenceError: regeneratorRuntime не определен

Конфиг

Вот моя конфигурация веб-пакета:

{
  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, как и перед манифестом, поставщик загружается, но поставщик выполняется непосредственно перед загрузкой приложения. В этом случае проблема в том, что разделение имеет плохой эффект: куски дублируются в vendor и app.

Что делать ?

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

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

person DEY    schedule 27.04.2018    source источник
comment
Я бы попытался присмотреться к плагинам Babel. Может быть, использовать babel-preset-env. Что не так с добавлением babel-polyfill в конфигурацию веб-пакета? Однако, если вам это не нравится, поместите только babel-regenerator-runtime, посмотрите здесь: stackoverflow.com/a/36590887/3233796   -  person proti    schedule 27.04.2018
comment
babel не имеет отношения, это будет та же проблема, например, с script-load! jquery. Может быть, это неясно, но я хочу, чтобы babel-polyfill был в комплекте поставщика, а не в наборе приложений.   -  person DEY    schedule 27.04.2018


Ответы (1)


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

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 сообщает веб-пакету, что приложение требует полифилла. И пакет, определенный в поставщике, сообщает плагину splitChunk, какие пакеты объединять в группу кеша.

Учитывая мое понимание из документа split-chunks-plugin

Параметр test определяет, какие модули выбираются этой группой кэша. Если его не указать, будут выбраны все модули.

Таким образом, удаление 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',
    ],
  },
  // ...

Это гарантирует, что полифилл требуется приложению.

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

person Pegase745    schedule 27.04.2018