使用 WebPack CommonsChunkPlugin 提取重复的 javascript 代码
Extract duplicate javascript code using WebPack CommonsChunkPlugin
我正在使用 WebPack CommonsChunkPlugin 来提取重复代码并减少 JavaScript 代码大小。我有两个 html 页和两个条目。我还添加了 ReactJs 供应商条目。到目前为止,在 webpack.config.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:
大家可以看到,有一些重复的代码,有的在红色区域,有的在绿色区域。我想从 home 和 about bundle 中提取这个 js 代码到一个单独的 bundle 中。要提取红色区域代码,即 lodash 库,我将这些行添加到 webpack 配置中:
new webpack.optimize.CommonsChunkPlugin({
name: 'lodash',
minChunks: function(module, count) {
return module.context.indexOf('node_modules/lodash') >= 0;
}
}),
但它没有按预期工作,lodash 库代码仍在 home 和 about 包中,webpack 还创建了一个名为 lodash 的包,它几乎是空的,不包含任何 js 库。
知道如何解决吗?提取绿色代码如何?
您的问题是您在每个 .js/.jsx
文件中导入第三方库,而不是之前在公共文件(通常称为 vendor.js
)中导入它。
如果你有这个导入所有依赖项的文件,并将它作为入口包含到 CommonsChunkPlugin,webpack 将不会再次将你的库包含在你的最终包中(home.js
和 about.js
).该技术在 webpack 文档中称为 code splitting。
vendor.js(或适合您情况的名称)
import 'react';
import 'react-dom';
import 'lodash';
import 'semantic-ui-react';
//... all your npm packages
webpack.config.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 ...
};
index.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 配置是:
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']
},
};
现在包分析器的输出是这样的:
如图所示,通用语义-ui-react 和 lodash 库现在只是在通用包中,不再重复。
我正在使用 WebPack CommonsChunkPlugin 来提取重复代码并减少 JavaScript 代码大小。我有两个 html 页和两个条目。我还添加了 ReactJs 供应商条目。到目前为止,在 webpack.config.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:
大家可以看到,有一些重复的代码,有的在红色区域,有的在绿色区域。我想从 home 和 about bundle 中提取这个 js 代码到一个单独的 bundle 中。要提取红色区域代码,即 lodash 库,我将这些行添加到 webpack 配置中:
new webpack.optimize.CommonsChunkPlugin({
name: 'lodash',
minChunks: function(module, count) {
return module.context.indexOf('node_modules/lodash') >= 0;
}
}),
但它没有按预期工作,lodash 库代码仍在 home 和 about 包中,webpack 还创建了一个名为 lodash 的包,它几乎是空的,不包含任何 js 库。
知道如何解决吗?提取绿色代码如何?
您的问题是您在每个 .js/.jsx
文件中导入第三方库,而不是之前在公共文件(通常称为 vendor.js
)中导入它。
如果你有这个导入所有依赖项的文件,并将它作为入口包含到 CommonsChunkPlugin,webpack 将不会再次将你的库包含在你的最终包中(home.js
和 about.js
).该技术在 webpack 文档中称为 code splitting。
vendor.js(或适合您情况的名称)
import 'react';
import 'react-dom';
import 'lodash';
import 'semantic-ui-react';
//... all your npm packages
webpack.config.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 ...
};
index.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 配置是:
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']
},
};
现在包分析器的输出是这样的:
如图所示,通用语义-ui-react 和 lodash 库现在只是在通用包中,不再重复。