Webpack 4 - Миграция из CommonsChunkPlugin с помощью SplitChunksPlugin - PullRequest
0 голосов
/ 16 сентября 2018

У нас есть традиционное приложение, отображаемое на сервере (не SPA), где каждая страница дополняется с помощью vuejs

Существующая конфигурация веб-пакета 3:

webpack.config.js

var webpack = require('webpack')
var path = require('path')

const ExtractTextPlugin = require('extract-text-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
    entry: {
        shared: './shared.js',
        pageA: './pageA.js',
        // pageB: './pageB.js',
        // pageC: './pageC.js',
        // etc
    },

    resolve: {
        alias: { vue: 'vue/dist/vue.esm.js' },
    },

    output: {
        path: path.join(__dirname, './dist'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                exclude: /node_modules/,
                use: ExtractTextPlugin.extract({
                    use: [
                        {
                            loader: 'css-loader',
                            query: {
                                sourceMap: true,
                            },
                        },
                    ],
                }),
            },
        ],
    },

    plugins: [
        new CleanWebpackPlugin('./dist'),

        new webpack.optimize.CommonsChunkPlugin({
            name: ['shared'],
            minChunks: Infinity,
        }),

        new webpack.optimize.CommonsChunkPlugin({
            name: 'runtime',
        }),

        new ExtractTextPlugin('[name].css'),

        new CopyWebpackPlugin([{ from: 'index.html', to: '.' }]),
    ],
}

shared.js

// import shared dependencies & pollyfills
var vue = require('vue')

// import global site css file
require('./shared.css')

// initialize global defaults
// vue.setDefaults(...)

console.log('shared', { vue })

pageA.js

var vue = require('vue')

// only this page uses axios
var axios = require('axios')

console.log('pageA', { vue, axios })

shared.css

body {
    background-color: aquamarine;
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- included on every page-->
    <link rel="stylesheet" href="shared.css">
</head>
<body>
    <!-- included on every page-->
    <script src="runtime.js"></script>
    <script src="shared.js"></script>

    <script src="pageA.js"></script>
</body>
</html>

Сэта настройка

1) runtime.js содержит загрузчик веб-пакетов, поэтому любые изменения в shared.js не приводят к отключению кэша pageA.js и наоборот

2) shared.jsсодержит любые общие зависимости (в данном случае vue), а также общую глобальную инициализацию для каждой страницы (установка vue по умолчанию и т. д.).Также он указывает, что мы импортируем наш общий глобальный css-файл.

3) pageA.js не содержит каких-либо зависимостей, импортированных в shared.js (в данном случае vue), но содержит зависимости, импортируемые им (axios в данном случае).

Нам не удалось воспроизвести эту настройку, используя SplitChunksPlugin

1) SplitChunksPlugin, по-видимому, не допускает точку входа в качестве точки разделения.

2) Все примеры разделили зависимости модуля ВСЕХ узлов на порцию вендора.Это не работает для нас, так как у нас есть сотни страниц, но только некоторые импортируют графическую библиотеку или момент и т. Д. Мы не хотим включать эту графическую библиотеку или момент в shared.js, так как она будет загружена длявсе страницы.

3) Неясно, как разбить среду выполнения на собственный файл.

SplitChunksPlugin, по-видимому, нацелены на SPA, где javascript может быть загружен по требованию.Сценарий, который мы трагируем, все еще поддерживается?

Ответы [ 2 ]

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

Если вы хотите, чтобы веб-пакет разделял какой-либо компонент, вам нужно будет асинхронно импортировать его из основного файла ввода. Я использовал для этого пакетный загрузчик, тогда у меня есть:

В моем webpack.config.js

optimization: {
  splitChunks: {
    chunks: 'all'
  },
  mergeDuplicateChunks: true,
}
module: {
  rules: [
    {
      test: /\.bundle\.js$/, //yes my output file contains the bundle in its name
      use: {
        loader: 'bundle-loader', options: {lazy: true}
      }
    }
  ]
}

В моем файле входа.

//this code will replace the line where you are importing this component
let Login;

// this method will go inside your component
componentWillMount() {
    require("bundle-loader!./ui/Login.jsx")((loginFile) => {
        Login = loginFile.default;
        this.setState({ loginLoaded: true });
    });
}

Если вы не хотите его использовать, есть другие способы импортирования файла в асинхронном режиме.

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

Вы пытаетесь перейти на webpack 4?

Я считаю, что optimisation cacheGroups test option хорошо работает, чтобы быть конкретным в том, что и куда идет.

optimization: {
  splitChunks: {
    cacheGroups: {
      shared: {
        test: /node_modules[\\/](?!axios)/,
        name: "shared",
        enforce: true,
        chunks: "all"
      }
    }
  }
}

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

...