Извлечение дублированного кода javascript с помощью Webpack CommonsChunkPlugin

Я использую WebPack CommonsChunkPlugin чтобы извлечь дубликат кода и уменьшить размер кода JavaScript. У меня есть две html-страницы и две записи для них. Также я добавил ReactJs запись поставщика. Пока что в webpack.конфиг.js у нас есть:

var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
    context: __dirname,
    entry: {
        react: ["react", "react-dom"],
        home: './assets/js/home.jsx',
        about: './assets/js/about.jsx',
    },

    output: {
        path: path.resolve('./assets/bundles/'),
        filename: "[name].js",
    },

    plugins: [
        new BundleTracker({filename: './webpack-stats.json'}),

        new webpack.optimize.CommonsChunkPlugin({
            name: 'react',
            minChunks: Infinity
        }),

        new BundleAnalyzerPlugin(),
    ],

    module: {
        rules: [
            {
              test: /.jsx?$/, 
              exclude: /node_modules/,
              loader: 'babel-loader',
              options: { 
                  plugins: [["lodash", { "id": ["semantic-ui-react"] }]],
                  presets: ["es2015", "react"]
              }  
            },
        ],
    },

    resolve: {
        modules: ['node_modules', 'bower_components'],
        extensions: ['*', '.js', '.jsx']
    },
};

этот результат конфигурации с webpack-bundle-analyzer:

webpack bundle analyzer output

Как вы можете видеть, там некоторые дублируют код, некоторые в красной области, а некоторые другие в зеленой области. Я хочу извлечь эти коды js из дома и о связках в отдельный пакет. Для извлечения кода красной области, а именно лодашь библиотека, я добавил Эти строки в конфиг webpack:

new webpack.optimize.CommonsChunkPlugin({
    name: 'lodash',
    minChunks: function(module, count) {
        return module.context.indexOf('node_modules/lodash') >= 0;
    }
}), 

но он работает не так, как ожидалось, и код библиотеки lodash все еще находится как дома, так и в пакетах, также webpack создает пакет с именем lodash, который почти пуст и не содержит js библиотека.

есть идеи, как это исправить ? Как насчет извлечения зеленых кодов?

2 ответов


ваша проблема в том, что вы импортируете сторонние библиотеки в каждом .js/.jsx файл без импорта его ранее в общий файл (обычно называемый vendor.js).
Если у вас есть этот файл, который импортирует все ваши зависимости, и вы включаете его в качестве записи и в CommonsChunkPlugin, webpack не будет снова включать ваши библиотеки в ваши окончательные пакеты (home.js и about.js). Техника называется разделение кода в webpack доктора.

поставщика.js (или именем, которое подходит для вашего случая)

import 'react';
import 'react-dom';
import 'lodash';
import 'semantic-ui-react';
//... all your npm packages

webpack.конфиг.js

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

module.exports = {
    context: __dirname,
    entry: {
        vendor: './assets/js/vendor.js,
        home: './assets/js/home.jsx',
        about: './assets/js/about.jsx',
    },
    output: {
        path: path.resolve('./assets/bundles/'),
        filename: '[name].js',
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks: Infinity
        }),
    ],

    //Rest of Your config ...
};

.HTML-код

<body>
    <!-- AFTER YOUR HTML CODE -->

    <script type="text/javascript" src="/assets/bundles/vendor.js"></script>
    <script type="text/javascript" src="/assets/bundles/home.js"></script>
    <script type="text/javascript" src="/assets/bundles/about.js"></script>
</body>


проверьте документы разделения кода webpack:


мне удалось решить проблему, добавив общий кусок в плагины. Таким образом, окончательный webpack config:

var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');

module.exports = {

    context: __dirname,

    entry: {
        react: ["react", "react-dom"],
        home: './assets/js/home.jsx',
        about: './assets/js/about.jsx',
    },

    output: {
        path: path.resolve('./assets/bundles/'),
        filename: "[name].js",
    },

    plugins: [

        new BundleTracker({filename: './webpack-stats.json'}),

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

        new webpack.optimize.CommonsChunkPlugin({
            name: 'common',
            chunks: ['home', 'about'],
            filename: '[name].js',
        }),
    ],

    module: {
        rules: [
            {
                test: /\.jsx?$/, 
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: { 
                    plugins: [
                      ["lodash", { "id": ["semantic-ui-react"] }]
                    ],
                    presets: ["es2015", "react"]
                }
            },
        ],
    },

    resolve: {
        modules: ['node_modules', 'bower_components'],
        extensions: ['*', '.js', '.jsx']
    },
};

и теперь вывод анализатора пакетов выглядит так:

analyzer output

как показано на рисунке, общие библиотеки semantic-ui-react и lodash теперь находятся в общем пакете и больше не дублируются.