A higher order component for loading components with promises
npm install @react-loadable/revisedCheck the old readme here.
The new package name: @react-loadable/revised.
There are several bugs in the original react-loadable package.
The author abandoned it a long time ago.
This is a revised and actively maintained version of the original package.
Exported APIs
``javascript`
import babelPlugin from '@react-loadable/revised/babel'
import {ReactLoadablePlugin} from '@react-loadable/revised/webpack'
import loadable, {preloadReady, preloadAll, Capture} from '@react-loadable/revised'
import {Capture} from '@react-loadable/revised'
- babelPlugin: babel plugin.ReactLoadablePlugin
- : webpack plugin.loadable
- : the main component to wrap your component.preloadReady
- : to load the pre-loaded components, used in client.preloadAll
- : to load all, used in server.getBundles
- : determine which bundles are required.Capture
- : the wrapper context, used in server, to capture the pre-loaded components.
Include '@react-loadable/revised/babel' in your babel plugin list.
This is required for both client and server builds.
In .babelrc:
`json`
{
"plugins": [
["@react-loadable/revised/babel", { "absPath": true }]
]
}
The babel plugin finds all calls to loadable({loader() {}, ...}),import()
scans all call in loader's body,loadable()
and inject the module identifiers to the object passed to for later uses.
For example, it transforms:
`javascript`
loadable({
loader() {
return import('./ExampleNested')
},
loading: Loading,
})
into:
`javascript`
loadable({
loader() {
return import('./ExampleNested')
},
modules: ['./ExampleNested'],
webpack() {
return [require.resolveWeak('./ExampleNested')] // will be evaluated by Webpack to ['./example/components/ExampleNested.js']
},
loading: Loading,
})
Webpack plugin is required only in your client build.
Include it in the webpack config's plugin list.
`javascript
const {writeFile} = require('fs/promises')
plugins: [
new ReactLoadablePlugin({
async callback(manifest) {
// save the manifest somewhere to be read by the server
await writeFile(
path.join(__dirname, 'dist/react-loadable.json'),
JSON.stringify(manifest, null, 2)
)
},
absPath: true,
}),
]
`
Wrap your split components with loadable({loader() {}, ...}) to get the lazily loadable component.
Sample code:
`javascript`
const LoadableNested = loadable({
loader() {
return import('./ExampleNested')
},
loading: Loading
})
Note: you must call loadable({...}) at the top-level of the module.preloadAll()
Otherwise, make sure to call them all (via importing) before calling or preloadReady().
- Call and await for preloadAll() once in the server side to pre-load all the components.
- For example: when the server starts serving.
`javascript`
await preloadAll()
app.listen(3000, () => {
console.log('Running on http://localhost:3000/')
})
- Load the exported react-loadable.json file, which is generated by the webpack plugin, to get the manifest.
`javascript`
// in production, this should be cached in the memory to reduce IO calls.
const getStats = () => JSON.parse(fs.readFileSync(path.resolve(__dirname, 'dist/react-loadable.json'), 'utf8'))
- Wrap the rendered component with Capture to capture the pre-loaded components.
`javascript`
const modules = [] // one list for one request, don't share
const body = ReactDOMServer.renderToString(
)
- After rendering the component, use getBundles() to determine which bundles are required.
`javascript`
const {assets, preload, prefetch} = getBundles(getStats(), modules)
- Inject the required bundles and rendered body to the html document and returns to the client.
`javascript
const Links = ({assets, prefetch}) => {
const urls = assets.filter(file => file.endsWith('.css'))
return prefetch
? urls.map((url, index) => )
: urls.map((url, index) => )
}
const Scripts = ({assets, prefetch}) => {
const urls = assets.filter(file => file.endsWith('.js'))
return prefetch
? urls.map((url, index) => )
: urls.map((url, index) =>