Извлечение дублированного кода 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:
Как вы можете видеть, там некоторые дублируют код, некоторые в красной области, а некоторые другие в зеленой области. Я хочу извлечь эти коды 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']
},
};
и теперь вывод анализатора пакетов выглядит так:
как показано на рисунке, общие библиотеки semantic-ui-react и lodash теперь находятся в общем пакете и больше не дублируются.