Loadable.Capture not reporting any modules

2020-08-13 07:21发布

问题:

This is essentially all my code. I am running Hapi and trying to use react-loadable to server render my React application.

I have added a lot of the missing pieces to the code here.

const location = req.url.pathname
const context = {}
const modules = []

const Router = () => (
  <Switch>
    <Route exact path="/" component={Home} />
    <Route path="/login" component={Login} />
    <Route path="/me" component={Profile} />
    <Route component={NotFound} />
  </Switch>
)

const App = () => (
  <StaticRouter location={location} context={context}>
    <main>
      <Header />
      <Router />
      <Footer />
    </main>
  </StaticRouter>
)

const preloadables = [ Home, Login, Profile, NotFound ]
await Promise.all(preloadables.map(preloadable => preloadable.preload()))

const html = ReactDOMServer.renderToString(
  <Loadable.Capture report={moduleName => modules.push(moduleName)}>
    <App/>
  </Loadable.Capture>
)

// render html

It renders the page correctly, as I see my React app rendered in my browser. Although I do not see any contents of the "Router" unless I disable cache on the server. So the first request renders no router, and the following ones do.

On the server, console.log('modules:', modules) returns modules: [] always. Regardless of cache. So even when I disable cache, refresh the page twice to see the router working, modules is still empty.

npm run start:server
Warning: setState(...): Can only update a mounting component. This usually means you called setState() outside componentWillMount() on the server. This is a no-op.

Please check the code for the LoadableComponent component.
modules []
modules []
modules []
modules []
modules []

I am a bit lost since it should be working.. everything looks okay.

回答1:

Today after somehow long struggle, solved it finally.

Before you get modules, you have to write your loadable component correctly. Official docs declare here

Loadable({
  loader: () => import('./Bar'),
  modules: ['./Bar'],
  webpack: () => [require.resolveWeak('./Bar')],
});

Or you can use babel plugin provided. However, as the situation for me, i'm using ts-node and with no luck of use that babel plugin, so only option 1 is available.

Write here for someone would encounter similar problem.

(p.s. lodable-component depends on babel plugin too)



回答2:

Seems that even though you loaded the components, react-loadable is not aware of them.

If you used Loadable.preloadAll instead of loading components programmatically, it should solve your problem.

Your current approach will also get very verbose when number of routes increases, you will have to maintain the list of preloadables.