reactjswebpackcode-splitting

React Code-Splitting: ChunkLoadError: Loading chunk 0 failed


I'm trying to introduce code-splitting to my project, but I'm having trouble getting it to work. The error I get is:

enter image description here

I have a monorepo setup with a lib/ workspace that contains the entire react library I'm creating, and a demo/ workspace that just imports that react module and displays it, for testing purposes.

I think the issue is how these two interact and where the chunks are output or something, but can't figure it out.

My files are like this:

lib/webpack.config.js

var path = require('path')

module.exports = {
  entry: {
    maps: './src/index.js'
  },
  output: {
    path: __dirname + '/dist',
    filename: 'index.js',
    library: 'Map',
    libraryTarget: 'umd'
  },
  module: {
    rules: [
      {
        test: /\.[s]?css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              modules: {
                  localIdentName: "[name]__[local]___[hash:base64:5]",
                }
            }
          },
          'sass-loader'
        ],
        include: /\.module\.[s]?css$/
      },
      {
        test: /\.[s]?css$/,
        use: ['style-loader', 'css-loader', 'sass-loader'],
        exclude: /\.module\.[s]?css$/
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            rootMode: 'upward'
          }
        }
      },
      {
        test: /\.svg$/,
        use: ['@svgr/webpack']
      },
      {
        test: /\.(jpe?g|png)$/i,
        loader: 'file-loader?name=/public/icons/[name].[ext]'
      }
    ]
  },
  resolve: {
    modules: [
      path.resolve(__dirname, 'src'),
      path.resolve(__dirname, '../node_modules')
    ],
    extensions: ['.js', '.jsx']
  },
  externals: {
    // Use external version of React
    react: 'react',
    'react-dom': 'react-dom'
  },
  // NOTE: @claus added options to fix files not being watched
  watchOptions: {
    aggregateTimeout: 300,
    poll: 1000
  }
}

Folder structure

lib/ // In this project we try to use code splitting using React.Lazy()
  package.json
  webpack.config.js
demo/ // Includes the lib module for testing purposes
  package.json
babel.config.js
package.json

demo/package.json

{
  "name": "demo",
  "version": "0.1.0",
  "license": "MIT",
  "dependencies": {
    "maps": "link:../map/"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version",
      "ie 11"
    ]
  }
}

Solution

  • The error is thrown when trying to load a bundle chunk that isn't available.

    It is my understanding that code splitting is used for applications, not libraries.

    Using code splitting for a library would mean that you would have to deliver multiple chunks as dist - not a single file like your settings

        path: __dirname + '/dist',
        filename: 'index.js',
    

    I'm not sure code splitting works for libraries - or what would be the benefit of it.

    Using code splitting in demo means that needed pieces from lib will be bundled in demo's chunks. You would have to use React.lazy in demo, not in lib, and when building demo, each React.lazy will generate a new bundle. demo has access to all the lib source files (or single file dist) and only what is needed will end up in the built app.

    I would guess you used React.lazy in lib and this mixes things up.

    I hope this helps!


    Extra questions/info:

    1. why do you need code-splitting? is your demo app bundle getting too big?
    2. Take a look at webpack's tree-shaking and make sure your lib is tree-shakable :) This way you can use code splitting in demo and not worry about it in lib