How do you use React lazy to code split with Babel & Webpack?

Viewed 419

I have a project where I would like to have route based bundle splitting. https://reactjs.org/docs/code-splitting.html & https://webpack.js.org/guides/code-splitting/ is what I've been looking at to understand it. Every resource I come across seems to show the bundle being split whenever the dynamic import syntax is used. Mine does not do that. I believe my Webpack or Babel are somehow making it not work based on various things I've read online. Could someone please help, I've been stuck on it for days.

Here's my routes `

import React, { lazy, Suspense } from 'react';
import { Route, Switch } from 'react-router-dom';
import {
  Navbar,
  Footer,
  HomePage,
} from '../app/components/';

function Routes() {
  return (
    <div>
      <Navbar />
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route exact path='/' component={HomePage}/>
          <Route
            path='/learn'
            component={lazy(() => import('./components/FAQ'))}
          />
          <Route
            path='/contact'
            component={lazy(() => import('./components/Contact'))}
          />
          <Route
            path='/login'
            component={lazy(() => import('./components/Login'))}
          />
          <Route
            path='/forgot-password'
            component={lazy(() => import('./components/ForgotPassword'))}
          />
        </Switch>
      </Suspense>
      <Footer />
    </div>
  );
}

`

Here's my webpack.config.js `

const Dotenv = require('dotenv-webpack');
module.exports = () => {
  return {
    entry: ['./app/index.js'],

    mode: 'development',
    output: {
      path: __dirname,
      filename: '[name].bundle.js',
    },
    devtool: 'source-map',
    resolve: {
      extensions: ['.js', '.jsx'],
    },
    plugins: [new Dotenv()],
    module: {
      rules: [
        {
          test: /\.jsx?$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
          },
        },
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader'],
        },
        {
          test: /\.m?js/,
          resolve: {
            fullySpecified: false,
          },
        },
        {
          test: /\.(png|jp(e*)g|svg|gif)$/,
          use: [
            {
              loader: 'file-loader',
              options: {
                name: 'images/[hash]-[name].[ext]',
              },
            },
          ],
        },
      ],
    },
  };
};

`

Here's my .babelrc `

{
  "presets": [
    "@babel/preset-react",
    ["@babel/preset-env", { "modules": false }]
  ],
  "plugins": ["@babel/transform-runtime", "@babel/plugin-syntax-dynamic-import"]
}

`

Here's my package.json `

{
  "name": "my-react-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "lint": "",
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon index.js",
    "start-dev": "webpack -w & nodemon index.js",
    "build-client": "webpack",
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.13.0",
    "@babel/runtime": "^7.16.3",
    "dotenv-webpack": "^7.0.3",
    "eslint": "^7.32.0",
    "express": "^4.17.1",
    "ify-loader": "^1.1.0",
    "morgan": "^1.10.0",
    "react": "^17.0.1",`enter code here`
    "react-dom": "^17.0.1",
    "react-redux": "^7.2.2",
    "react-router-dom": "^5.2.0",
    "react-scroll": "^1.8.3",
    "redux": "^4.0.5",
    "redux-devtools-extension": "^2.13.8",
    "redux-logger": "^3.0.6",
    "redux-thunk": "^2.3.0",
  },
  "devDependencies": {
    "@babel/core": "^7.13.1",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/plugin-transform-runtime": "^7.16.4",
    "@babel/preset-react": "^7.12.13",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.0.2",
    "dotenv": "^8.6.0",
    "file-loader": "^6.2.0",
    "prettier": "2.3.2",
    "style-loader": "^2.0.0",
    "webpack": "^5.24.0",
    "webpack-cli": "^4.5.0"
  }
}

`

Here's what it looks like when I run npm run build-client client build

Any sort of guidance as to what to look into would be appreciated. Thank you!

1 Answers

It seems that it has to be done in another way?

import React, { lazy, Suspense } from 'react';
import { Route, Switch } from 'react-router-dom';
import {
  Navbar,
  Footer,
  HomePage,
} from '../app/components/';

const FAQ = lazy(() =>import('./components/FAQ'))
const Contact = lazy(() =>import('./components/Contact'))
const Login = lazy(() =>import('./components/Login'))
const ForgotPassword = lazy(() =>import('./components/ForgotPassword'))

function Routes() {
  return (
    <div>
      <Navbar />
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route exact path='/' component={HomePage}/>
          <Route
            path='/learn'
            component={FAQ}
          />
          <Route
            path='/contact'
            component={Contact}
          />
          <Route
            path='/login'
            component={Login}
          />
          <Route
            path='/forgot-password'
            component={ForgotPassword}
          />
        </Switch>
      </Suspense>
      <Footer />
    </div>
  );
}

Related