Equivalent to preloadAll
See original GitHub issueI was upgrading our existing app from react-loadable
to @loadable/components
. In my previous server-side configuration I was relying on preloadAll
from react-loadable to initialize all of the loadable components before starting my app.
Looking at the server-side example for loadable-compoents you are doing something similar in nodeExtractor.requireEntrypoint()
.
My problem: My app is set up slightly differently than the example and using requireEntrypoint
would mean a significant refactor.
Why? Long ago we made the decision to build the entire express server using webpack/babel. In the example you build the react app twice with the exact same entrypoint and build the express server separately. That’s an interesting approach but it’s not the only approach.
Why preloadAll
? You have recognized this issue on the client and provided a dedicated loadableReady
function. On the server it would be nice to be able to resolve all loadables prior to running the app. Using requireEntrypoint
only works if you’re initializing a separately built app. Something like preloadAll
allows you to initialize the app from within the bundle itself.
preloadAll
is pretty clever. It works by keeping an internal reference for every loadable. It would be like adding to an array every time loadable
is called. It then loops through those references recursively when preloadAll
is called. Because it resolves each loadable recursively it’s able to initialize the entire tree without the need to have a separate stats file for the server build.
In a server-side context the penalty is a brief pause while the server is initializing. Having something like preloadAll
available would make it far easier to integrate loadable-components into a project that had been successfully running react-loadable 5.
Chicken and egg: There are some interesting issues with the way preloadAll
works if you don’t use node-externals in your server bundle. In the past I had designed apps to work more similarly to the server-side example and had issues with preloadAll
. Something like requireEntrypoint
would’ve made my life easier. However, I was able to solve the issue by re-exporting preloadAll
from my entrypoint to ensure that it was referencing the version of react-loadable in the bundle. That way my server was able to import App
and preloadAll
to initialize the bundle before using it.
Example:
const { default: App, preloadAll } = require(path.resolve(
__dirname,
'../../public/dist/node/main.js',
))
const webStats = path.resolve(
__dirname,
'../../public/dist/web/loadable-stats.json',
)
app.get(
'*',
(req, res) => {
const extractor = new ChunkExtractor({ statsFile: webStats })
const jsx = extractor.collectChunks(<App />)
const html = renderToString(jsx)
res.set('content-type', 'text/html')
res.send(`<!DOCTYPE html>
<html>
<head>
${extractor.getLinkTags()}
${extractor.getStyleTags()}
</head>
<body>
<div id="main">${html}</div>
${extractor.getScriptTags()}
</body>
</html>`)
},
)
preloadAll().then(() => {
app.listen(9000, () => console.log('Server started http://localhost:9000'))
})
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (4 by maintainers)
Top GitHub Comments
I don’t need a
preloadAll
if I replace https://github.com/smooth-code/loadable-components/blob/0d3e7dee3045737be1709ffa300aca083aef457c/packages/component/src/createLoadable.js#L166-L171 withThe dynamic naming works with Node, with Webpack it’s confusing at the time of the build but Node has everything to make a require that works at the time of the execution. If there is a variable in the name, it is resolved in Node, not for webpack.
This code works perfectly with my modification if the
part
variable is not invalid:And it will work for full-dynamic as well.
I also need a
preloadAll
, my server makes a page empty the first time and works for all subsequent times.edit: I use esm for node.