Как использовать Webpack 4 SplitChunksPlugin с HtmlWebpackPlugin для многостраничного приложения? - PullRequest
0 голосов
/ 11 июня 2018

Я пытаюсь использовать SplitChunksPlugin для создания отдельных пакетов для каждой страницы / шаблона в MPA.Когда я использую HtmlWebpackPlugin, я получаю html-файл для каждой страницы с тегом скрипта, указывающим на правильный пакет.Это прекрасно!Однако у меня проблема с файлами поставщиков.Я хочу, чтобы отдельные html-файлы указывали только на те пакеты поставщиков, которые им нужны.Я не могу заставить каждый отдельный html-файл указывать на правильные пакеты поставщиков, когда SplitChunksPlugin создает несколько пакетов поставщиков.Были получены следующие пакеты:

home.bundle.js
product.bundle.js
cart.bundle.js
vendors~cart~home~product.bundle.js
vendors~cart~product.bundle.js

Таким образом, в основном шаблон home должен ссылаться на home.bundle.js, vendors ~ cart ~ home ~ product.bundle.js, а не на второй пакет vendor.Только корзина и шаблоны продуктов должны ссылаться на оба комплекта поставщиков.Я использую опцию chunks для HtmlWebpackPlugin, но не могу заставить его извлекать правильные пакеты поставщиков, если я явно не ссылаюсь на его имя, например, так:

chunks: ['vendors~cart~home~product.bundle','home']

Но это своего рода побеждает цель динамического рендерингаваш скрипт теги.Я пытался создать точку входа поставщика, но это объединяет всех моих поставщиков.Мне не хватает какой-нибудь простой конфигурации?

Мой webpack.config.js:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const Visualizer = require('webpack-visualizer-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    entry: {
        home: './src/js/page-types/home.js',
        product: './src/js/page-types/product.js',
        cart: './src/js/page-types/cart.js'
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist/js')
    },
    optimization: {
        splitChunks: {
            chunks: 'all'
        }
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new Visualizer(),
        new HtmlWebpackPlugin({
            filename: 'home.html',
            chunks: ['vendors','home']
        }),
        new HtmlWebpackPlugin({
            filename: 'product.html',
            chunks: ['vendors','product']
        }),
        new HtmlWebpackPlugin({
            filename: 'cart.html',
            chunks: ['vendors~cart~product','cart']
        }),
    ], ...

Мои js-модули:

/* home.js */
    import jQuery from 'jquery';
    import 'bootstrap';

корзина и продукт также ссылкабиблиотека реагирования:

/* cart.js */
    import jQuery from 'jquery';
    import 'bootstrap';
    import React from 'react';
    import ReactDOM from 'react-dom';

/* product.js */
    import jQuery from 'jquery';
    import 'bootstrap';
    import React from 'react';
    import ReactDOM from 'react-dom';

Пример вывода html home.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
  <script type="text/javascript" src="home.bundle.js"></script></body>
</html>

Ответы [ 2 ]

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

Используйте версию 4 html-webpack-plugin (которая сейчас находится в бета-версии) и включайте только чанк записи в опцию chunks.

npm i -D html-webpack-plugin@next

и

module.exports = {
    new HtmlWebpackPlugin({
        filename: 'home.html',
        chunks: ['home']
    }),
    new HtmlWebpackPlugin({
        filename: 'product.html',
        chunks: ['product']
    }),
    new HtmlWebpackPlugin({
        filename: 'cart.html',
        chunks: ['cart']
    }),
};

Thisбудет автоматически включать связанные фрагменты.

0 голосов
/ 30 августа 2018

Один из вариантов - вручную создать чанки поставщика, а затем включить любой из этих чанков, необходимых для страницы, в параметр chunks из HtmlWebpackPlugin.

webpack.config.js:

const path = require('path');
const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const Visualizer = require('webpack-visualizer-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode: 'development',
    devtool: 'cheap-module-eval-source-map',
    entry: {
        home: './src/js/page-types/home.js',
        product: './src/js/page-types/product.js',
        cart: './src/js/page-types/cart.js'
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist/js')
    },
    optimization: {
        splitChunks: {
            cacheGroups: {
                'vendor-bootstrap': {
                    name: 'vendor-bootstrap',
                    test: /[\\/]node_modules[\\/](jquery|bootstrap)[\\/]/,
                    chunks: 'initial',
                    priority: 2
                },
                'vendor-react': {
                    name: 'vendor-react',
                    test: /[\\/]node_modules[\\/]react.*?[\\/]/,
                    chunks: 'initial',
                    priority: 2
                },
                'vendor-all': {
                    name: 'vendor-all',
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'initial',
                    priority: 1
                },
            }
        }
    },
    plugins: [
        new CleanWebpackPlugin(['dist']),
        new Visualizer(),
        new HtmlWebpackPlugin({
            filename: 'home.html',
            chunks: ['vendor-bootstrap', 'vendor-all', 'home']
        }),
        new HtmlWebpackPlugin({
            filename: 'product.html',
            chunks: ['vendor-bootstrap', 'vendor-react', 'vendor-all', 'product']
        }),
        new HtmlWebpackPlugin({
            filename: 'cart.html',
            chunks: ['vendor-bootstrap', 'vendor-react', 'vendor-all', 'cart']
        }),
    ], ...

Блок vendor-all предназначен для перехвата любых библиотек других поставщиков, которые не включены в другие блоки.

...