Как я могу использовать несколько записей в Webpack вместе с несколькими файлами HTML в HtmlWebpackPlugin? - PullRequest
0 голосов
/ 21 сентября 2018

Мы хотели бы получить два вывода из Webpack - все наше приложение со всеми его зависимостями и одну отдельную страницу только с одной зависимостью (которая не используется основным приложением).

Кажется, что способ сделать это - использовать свойство entry конфигурации Webpack.Однако этого недостаточно, поскольку мы также используем HtmlWebpackPlugin для вывода нашего HTML-файла с build.js, который динамически добавляется скомпилированным Webpack (а также скомпилированным LESS и т. Д.).Согласно документации HtmlWebpackPlugin:

Если у вас есть несколько точек входа Webpack, все они будут включены в теги сценария в сгенерированном HTML.

Это не будет работатьдля нас, поэтому мне нужно использовать их filterChunks вариант.Этот ответ на проблему GitHub гласит его наиболее кратко:

module.exports = {
  entry: {
    'page1': './apps/page1/scripts/main.js',
    'page2': './apps/page2/src/main.js'
  },
  output: {
    path: __dirname,
    filename: "apps/[name]/build/bundle.js"
  },
  plugins: [
    new HtmlWebpackPlugin({
      inject: false,
      chunks: ['page1'],
      filename: 'apps/page1/build/index.html'
    }),
    new HtmlWebpackPlugin({
      inject: false,
      chunks: ['page2'],
      filename: 'apps/page2/build/index.html'
    })
  ]
};

(в документации по HtmlWebpackPlugin это находится в разделе «Фильтрация чанков»)

Итак, я изменилнаш код выглядит так:

module.exports = {
    entry: {
        app: './public/js/ide.js',
        resetPassword: './public/js/reset_password.js'
    },
    output: {
        path: path.resolve(__dirname, '../build'),
        filename: '[name].js',
        publicPath: '/'
    },
    ...
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'public/html/ide.html',
            inject: true,
            chunks: ['app']
        }),
        new HtmlWebpackPlugin({
            filename: 'reset_password.html',
            template: 'public/html/reset_password.html',
            inject: true,
            chunks: ['resetPassword']
        }),
    ],
}

Теперь, когда я перестраиваю проект (сейчас пытаюсь только с WebpackDevServer) и перехожу на /index.html, я вижу на вкладке сети файл массивного пакета, содержимоеindex.html (на основе шаблона ide.html), а также запросы на различные внешние ресурсы.Однако на самом деле JavaScript не будет работать (скажем, console.log в ide.js).Весь HTML в файле показывает.

Для reset_password.html показывается весь HTML и файл reset_password.js, но ни один из javascript в пределах прогонов.

Как я могу обеспечить работу JavaScript в моих entry файлах?

РЕДАКТИРОВАТЬ : я получил ide.js работу, потому что я не понял, что это был "кусок":

optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendor',
                    chunks: 'all'
                }
            }
        }
    },

Итак, я добавил vendor в index.html HtmlWebpackPlugin chunks свойство.Теперь это выглядит так:

new HtmlWebpackPlugin({
    filename: 'index.html',
    template: 'public/html/ide.html',
    inject: true,
    chunks: ['app', 'vendor']
}),

reset_password ничего не нужно в папке node_modules, и это также не объясняет, почему никакой JavaScript вообще не будет работать внутри ide.js, поэтомуЯ все еще в замешательстве.Кроме того, reset_password по-прежнему не работает.

EDIT2 : просматривая прикрепленный файл reset_password.js при загрузке reset_password.html, я вижу эту строку

eval("\n\nconsole.log('DRAGONHELLO');//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9wdWJsaWMvanMvcmVzZXRfcGFzc3dvcmQuanM/ZjY5ZSJdLCJuYW1lcyI6WyJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiOztBQUNBQSxRQUFRQyxHQUFSLENBQVksYUFBWiIsImZpbGUiOiIuL3B1YmxpYy9qcy9yZXNldF9wYXNzd29yZC5qcy5qcyIsInNvdXJjZXNDb250ZW50IjpbIlxuY29uc29sZS5sb2coJ0RSQUdPTkhFTExPJylcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./public/js/reset_password.js\n");

Итак, ясно, мой console.log('DRAGONHELLO') «видно», но я понятия не имею, почему он не работает.

EDIT3 : добавление vendor к chunks для reset_password.html приводит к запуску JavaScript, но я понятия не имею, почему, и это не идеально, потому что весь смыслВ упражнении должно было быть две разные связки, одна из которых была очень минимальной и не требовала всех наших node_modules.

EDIT4 : я запустил Webpack с profile:true, и я вижу, что я неправильно понимаю «Имена чанков»:

                 js/app.3d18b43294ebd54ed083.js   1.34 MiB       0  [emitted]  [big]  app
       js/resetPassword.198485be2b163cc258ed.js   1.02 KiB       1  [emitted]         resetPassword
                   js/2.e7f92193ea3c611a0b36.js   2.23 MiB       2  [emitted]  [big]  vendor
             js/app.3d18b43294ebd54ed083.js.map   2.71 MiB       0  [emitted]         app
   js/resetPassword.198485be2b163cc258ed.js.map   4.57 KiB       1  [emitted]         resetPassword
               js/2.e7f92193ea3c611a0b36.js.map   7.12 MiB       2  [emitted]         vendor

EDIT5 : я пробовал

module.exports = {
  //...
  optimization: {
    runtimeChunk: {
      name: entrypoint => `runtime~${entrypoint.name}`
    }
  }
};

и

module.exports = {
  //...
  optimization: {
    runtimeChunk: true
  }
};

На основе комментария PlayMa256 и документов webpack на runtimeChunk .Ни один из них не вызвал выполнение JavaScript.

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Это многокомпонентный выпуск.

Во-первых, в Html-Webpack-Plugin есть ошибка, которая делает его несовместимым с Webpack4 и несколькими точками входа.Он должен быть обновлен до v4.0.0-alpha.2 как минимум для работы.

Во-вторых, в новой версии вам не нужно использовать optimization.splitChunks.cacheGroups для ручного разделения node_modules.Выполнение optimization.splitChunks.chunks = 'all' достаточно для того, чтобы данная точка входа только получила в свой vendors-app-{{chunk_name}} блок node_modules, на самом деле import s.

Итак, если вы сделаете

optimization: {
    splitChunks: {
        chunks: 'all'
    },
},

В сочетании с

plugins: [
    new HtmlWebpackPlugin({
        filename: 'index.html',
        template: 'public/html/ide.html',
        inject: true,
        chunks: ['app']
    }),
    new HtmlWebpackPlugin({
        filename: 'reset_password.html',
        template: 'public/html/reset_password.html',
        inject: true,
        chunks: ['resetPassword']
    }),
]

В сочетании с

entry: {
    app: './public/js/ide.js',
    resetPassword: './public/js/reset_password.js'
},

Тогда ваш вывод из веб-пакета будет иметь

  1. app
  2. resetPassword
  3. vendors ~ app ~ resetPassword
  4. vendors ~ app
  5. vendors ~ resetPassword

Если в вашем файле resetPassword.js нет imports, в этом случае оно будет выглядеть как

  1. app
  2. resetPassword
  3. vendors ~ app~ resetPassword (необходимые пакеты поставщиков веб-пакетов)
  4. vendors ~ app

Дополнительная информация, изображения и диалоги по адресу https://github.com/jantimon/html-webpack-plugin/issues/1053

Обратите внимание, что chunksSortMode: нетболее длинная допустимая опция для объекта HtmlWebpackPlugin для самой новой версии, по-видимому, это делается по умолчанию в webpack4.

0 голосов
/ 21 сентября 2018

Когда вы устанавливаете:

module.exports = {
  //...
  optimization: {
    runtimeChunk: true
  }
};

Генерирует блок времени выполнения.Что такое время выполнения?Во время выполнения ВСЕ код, который использует веб-пакет для загрузки других файлов.Это сердце веб-пакета, когда вы запускаете сборку.

Поскольку у вас есть 2 отдельных файла комплекта: resetPassword и app.

Хорошо, у вас есть все необходимые файлы.Возможно, вам тоже нужны поставщики для обоих, так как в вашем случае vendor содержит все от node_modules.Таким образом, в основном вы будете иметь:

html 1: app, vendor, runtimeChunk.

html 2: reset_password, vendor, runtimeChunk.

После этого ваше приложение должно запуститься.

...