问题
I'm currently working on a project and i need to configure WebPack. In the project, we are also using ReactJS and Semantic-UI. Here is webpack.config.js :
var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
context: __dirname,
entry: {
react: ["react", "react-dom"],
home: './assets/js/index.jsx',
},
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name].js",
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.optimize.CommonsChunkPlugin({
names: ["react"],
}),
new webpack.optimize.CommonsChunkPlugin({
name: "home",
chunks: ['home'],
filename: "[name]-[hash].js",
}),
new BundleAnalyzer(),
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: { presets: ["es2015", "react"] }
},
],
},
resolve: {
modules: ['node_modules', 'bower_components'],
extensions: ['*', '.js', '.jsx']
},
};
In assets/js/index.jsx file, we just have these import statements :
import React from "react";
import ReactDOM from 'react-dom';
import { Button } from 'semantic-ui-react';
By running webpack command, it outputs two files:
- react.js: 779 KB
- home-[some_hash_number].js: 1.5 MB
Using webpack-bundle-analyzer plugin, we get this:
As you see the red rectangle in the picture, all of the semantic-ui react components are bundled into home.js file although i just imported Button
component from in assets/js/index.js file and that's why the output file gets too big.
Is there any way to just bundle needed components?
UPDATE
Reading @Alexander Fedyashov answer, i installed babel-plugin-lodash and updated webpack.config.js accordingly:
var path = require("path");
var webpack = require('webpack');
var BundleTracker = require('webpack-bundle-tracker');
var BundleAnalyzer = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
context: __dirname,
entry: {
react: ["react", "react-dom"],
home: './assets/js/index.jsx',
},
output: {
path: path.resolve('./assets/bundles/'),
filename: "[name].js",
},
plugins: [
new BundleTracker({filename: './webpack-stats.json'}),
new webpack.optimize.CommonsChunkPlugin({
name: "react",
}),
new webpack.optimize.CommonsChunkPlugin({
name: "home",
chunks: ['home'],
filename: "[name]-[hash].js",
}),
new BundleAnalyzer(),
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
plugins: ["lodash", { "id": ["lodash", "semantic-ui-react"] }],
presets: ["es2015", "react"],
}
},
],
},
resolve: {
modules: ['node_modules', 'bower_components'],
extensions: ['*', '.js', '.jsx']
},
};
Now everything is working and only needed components are loaded.
回答1:
It should be splitted by Webpack, but in fact tree shaking doesn't work. You can use babel-plugin-lodash
as described in SUIR docs.
You should keep in mind, that some of SUIR's components are dependent from each other, i.e.:
Button
requiresIcon
andLabel
Label
requiresIcon
andImage
Image
requiresDimmer
Dimmer
requiresPortal
.
However, plugin will allow to strip such components as Rail
, Reveal
and Advertisement
if you don't use them.
回答2:
There is a new feature on Webpack 2 to solve this issue, read this article https://medium.com/@adamrackis/vendor-and-code-splitting-in-webpack-2-6376358f1923
来源:https://stackoverflow.com/questions/45386871/webpack-loads-all-semantic-ui-components