3

The main problem is while code splitting with react-routerV4 and then webpack 2, I have modules that are in several chunks that I can't get to the main one.

My configuration is as follow :

  • Webpack 2.2.1
  • React-route 4.1.1

I'm using the code splitting as in the react-router v4 documentation

Basically, I don't use the import, but on the route configuration I have : something like this :

import loadHome from 'bundle-loader?lazy&name=home-chunk!./pages/market/Home';
[
  {
    path: url1,
    component: props => <Bundle load={loadHome}>{Home => <Home {...props} />}</Bundle>,
    exact: true,
  },
  // other routes
  ]

This works totally fine with the code splitting and I get a bundle for each route and another bundle for the node_modules that I can later split.

My problem is, I have one node_module (react-slick) that is in several bundles. So I want to get it out in the main bundle.

My webpack configuration is :

module.exports = {
  entry: [
    'whatwg-fetch',
    './src/scripts/index.js',
  ],
  output: {
    path: path.resolve(__dirname, 'src/build'),
    publicPath: '/build/',
    chunkFilename: "[name].js?[hash]",
    filename: '[name].js',
  },
  plugins: [
    new BundleAnalyzerPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': '"production"'
      }
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: ['4_node-modules'],
      minChunks(module) {
       const context = module.context;
       return context && context.indexOf('node_modules') >= 0;
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: ['3_react'],
      chunks: ['4_node-modules'],
      minChunks(module) {
        return module.context && /.*\/react.*/.test(module.context);
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({
        children: true,
        minChunks: 2,
    }),
    new ExtractTextPlugin({
      filename: '[name].css',
      allChunks: true,
    }),
    new HtmlWebpackPlugin({
      filename: '../index.prod.html',
      template: 'src/template.index.prod.html',
      inject: false,
      hash: true,
    }),
  ],
};

According to the documentation, this should do the trick :

new webpack.optimize.CommonsChunkPlugin({
    children: true,
    minChunks: 2,
}),

But nothing happens, I still have "react-slick" in 3 of my bundles.

Does anyone have an hint of what's going on ?

Any help is appreciated :) Thank you !

2 Answers2

4

And I finally got the solution ;)

I let this so it might help someone.

The answer is : Not specifying chunk doesn't apparently target all the chunks but only the last one created.

So let's say with react-router V4 we've created 2 async chunks 'home-chunk' and 'welcome-chunk'. The way to get the common chunks out of it is to add in the webpack config file (in the pluggins):

new webpack.optimize.CommonsChunkPlugin( {
  name : 'common',
  chunks : ['home-chunk', 'welcome-chunk'],
  minChunks : 2,
}),

This will check if there is common modules in the async chunks and if so, put them in the common chunk.

-1

Answer below copied from here: How to remove duplicate Ant Design components across chunks


Solution without modifying webpack:

On the parent component (or a higher parent), do the exact same import here.

import { Row, Col, Button } from "antd"

You could use React.lazy to import here as well. I don't think it's necessary, but you could put this inside a useEffect so this code is only read by your app when that parent component mounts.

useEffect(() => {
  React.lazy(() => import("antd"))
}, []);

In the child component, import with the same code as normal to use the variables. Webpack recognises that this module has already been downloaded because the parent component still exists so it doesn't include them in new bundles.

import { Row, Col, Button } from "antd" 
Scott Wager
  • 758
  • 11
  • 9