Search code examples
node.jsreactjsbabeljswebpack-4react-loadable

React-Loadable SSR with Webpack 4 and Babel 7


Does server-side rendering with react-loadable work with Webpack 4 and Babel 7? I've been unable to get it working successfully while following the instructions.

After following just the client-side steps, Webpack correctly outputs separate chunks for each loadable component and this is reflected when I load the page in the browser (ie: the chunks are lazy-loaded).

After following all the SSR steps, however, the server throws the following error:

Error: Not supported
at loader (/Projects/test-project/web/routes/index.js:50:15)
at load (/Projects/test-project/web/node_modules/react-loadable/lib/index.js:28:17)
at init (/Projects/test-project/web/node_modules/react-loadable/lib/index.js:121:13)
at flushInitializers (/Projects/test-project//web/node_modules/react-loadable/lib/index.js:310:19)
at /Projects/test-project/web/node_modules/react-loadable/lib/index.js:322:5
at new Promise (<anonymous>)
at Function.Loadable.preloadAll (/Projects/test-project/web/node_modules/react-loadable/lib/index.js:321:10)
at Object.preloadAll (/Projects/test-project/web/server.js:15:10)
at Module._compile (internal/modules/cjs/loader.js:702:30)
at Module._compile (/Projects/test-project/web/node_modules/pirates/lib/index.js:83:24)

My routes/index.js file:

import React from 'react';
import Loadable from 'react-loadable';

import Loading from '../components/Loading';

export default [
  {
    path: '/',
    component: Loadable({
      loader: () => import('./controllers/IndexController'),
      loading: Loading,
    }),
    exact: true,
  },
  {
    path: '/home',
    component: Loadable({
      loader: () => import('./controllers/HomeController'),
      loading: Loading,
    }),
    exact: true,
  },
  ...
];

This issue on SO is possibly related to the server error I'm seeing above, but provided even less info.

My .babelrc is already using @babel/plugin-syntax-dynamic-import, but I tried adding babel-plugin-dynamic-import-node. This fixes the server issue but Webpack then no longer builds the chunks.

I've been unable to find a definitive example to get this working. There is conflicting info out there about proper setup. For example, the react-loadable README says to use the included react-loadable/babel plugin, while this post by the lib author says to use babel-plugin-import-inspector. This PR seemed to be attempting to address Webpack 4 issues but was closed, and the forked lib appeared to have issues as well.

I am using:

  • Babel 7
  • Node 10.4
  • React 16.5
  • React-Loadable 5.5
  • Webpack 4

Solution

  • I had the exact same problem today. After adding dynamic-import-node to the plugins of my .babelrc the server worked, but webpack wasn't creating the chunks. I then removed it again from my .babelrc and moved it to my server script with @babel/register. My server script now looks like this:

    require( "@babel/register" )({
        presets: ["@babel/preset-env", "@babel/preset-react"],
        plugins: ["dynamic-import-node"]
    });
    require( "./src/server" );
    

    I hope this helps ;)