Answer the question
In order to leave comments, you need to log in
How to implement dynamic import for code splitting in Webpack 2?
It would seem that everything is simple. We use a construction like:
import(/* webpackChunkName: "my-component-chunk" */ 'MyComponent').then((Component) => {
this.setState({ Component });
})
new webpack.optimize.CommonsChunkPlugin({
children: true,
async: true,
}),
...
//остальные статичные чанки типа 'vendor'
Answer the question
In order to leave comments, you need to log in
I found a solution, posted an answer to a similar question, and I'll write here. Everything is quite simple if you know the nuances:
1) You need to understand that what we want to download should be in a separate file - a chunk.
2) In order to create a chunk, you need to load all imports of this component "lazy". This is very important, at one time it was this that prevented me from splitting an existing project into chunks.
3) Well, the simplest: we load through the import promise:
const loadEditor = () => import(/* webpackChunkName: "my-best-editor-chunk" */ 'react-dart-editor');
loadEditor().then(m => use it);
new webpack.optimize.CommonsChunkPlugin({
children: true,
async: true,
minChunks: 2,
}),
new webpack.optimize.CommonsChunkPlugin('manifest'),
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Chunk extends Component {
state = { LoadedComponent: null };
componentWillMount() {
if (this.props.preload) this.load(this.props);
}
componentWillReceiveProps(nextProps) {
const { load, component, show } = nextProps;
if (
this.props.load !== load ||
this.props.component !== component ||
(this.props.show !== show && show)
) {
this.load(nextProps);
}
}
load(props) {
this.setState({ LoadedComponent: null });
props.load().then((mod) => {
this.setState({
LoadedComponent: props.component ? mod[props.component] : mod.default,
});
});
}
renderLoading = () => this.props.showLoading ? (<div>Loading</div>) : null;
render() {
const { LoadedComponent } = this.state;
const { show, ...props } = this.props;
delete props.load;
delete props.component;
if (!show) return null;
return LoadedComponent ? <LoadedComponent {...props} /> : this.renderLoading();
}
}
Chunk.defaultProps = {
showLoading: false,
preload : true,
show : true,
};
Chunk.propTypes = {
load : PropTypes.func.isRequired,
show : PropTypes.bool,
preload : PropTypes.bool,
component : PropTypes.string,
showLoading: PropTypes.bool,
};
export default Chunk;
<Chunk
load={loadEditor} // была уже выше
component="EditorAside" // если нужно что-то, что импортируется не по дефоулту
show={true/false} // отображать ли компотнент
preload={true/false} // осуществлять ли предзагрузку чанка
props1="1"
props2="2"
/>
UPD2: Solving the problem
You have the name entryPoint and that is what you need to specify as name when configuring commonChunksPlugin
entry: {
application: /* ... */
},
....
plugins: {
new webpack.optimize.CommonsChunkPlugin({
name: 'application', // <--- Так же как и entryPoint
async: "vendors", // <--- будет использовано как имя файла (можно оставить просто true). "vendors.js"
children: true,
minChunks: 2 // <--- должно быть >= 2
})
}
{
entry: {
main: './reactStartup.js'
},
output: {
filename: '[name]-bundle.js',
chunkFilename: '[name]-chunk.js',
path: path.resolve(__dirname, 'dist'),
publicPath: 'dist/'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
async: true,
children: true,
minChunks: 2,
}),
]
}
// .babelrc
{
"plugins": [
"syntax-dynamic-import"
]
}
"presets": [
[
"env",
{
"targets": {
"node": "current",
"browsers": "last 2 versions"
},
"modules": false,
"loose": true
}
],
"react",
],
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question