Package Exports
- @loadable/server
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@loadable/server) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@loadable/server
Install
npm install @loadable/serverModes
Loadable supports two modes, a static mode and a dynamic mode.
The static mode insert required chunks directly in the page whereas the dynamic mode loads them from your main bundle.
This table compares the two modes.
| Mode | @loadable/babel-plugin |
@loadable/webpack-plugin |
loadComponents() |
Perf |
|---|---|---|---|---|
| Static | Required | Required | Not required | ++ |
| Dynamic | Required | Required | Required | + |
Static Mode (recommended)
1. Install @loadable/babel-plugin
.babelrc
{
"plugins": ["@loadable/babel-plugin"]
}2. Install @loadable/webpack-plugin
webpack.config.js
const LoadablePlugin = require('@loadable/webpack-plugin')
module.exports = {
// ...
plugins: [new LoadablePlugin()],
}3. Setup LoadableState server-side (with manifest)
import path from 'path'
import { LoadableState } from '@loadable/server'
// This is the manifest generated by webpack
import manifest from '../dist/loadable-manifest.json'
const loadableState = new LoadableState(manifest)
const html = renderToString(
<LoadableStateManager state={loadableState}>
<YourApp />
</LoadableStateManager>,
)
const scriptTags = loadableState.getScriptTags() // or loadableState.getScriptElements();Dynamic mode
1. Install @loadable/babel-plugin
.babelrc
{
"plugins": ["@loadable/babel-plugin"]
}2. Install @loadable/webpack-plugin
webpack.config.js
const LoadablePlugin = require('@loadable/webpack-plugin')
module.exports = {
// ...
plugins: [new LoadablePlugin()],
}3. Setup LoadableState server-side (without manifest)
import path from 'path'
import { LoadableState } from '@loadable/server'
const loadableState = new LoadableState()
const html = renderToString(
<LoadableStateManager state={loadableState}>
<YourApp />
</LoadableStateManager>,
)
const scriptTags = loadableState.getScriptTags() // or loadableState.getScriptElements();4. Use loadComponents() client-side
import { hydrate } from 'react-dom'
import { loadComponents } from '@loadable/component'
// Call `loadComponents()` before rendering your application
loadComponents().then(() => {
hydrate(<YourApp />, root)
})Collecting chunks
The basic API goes as follows:
import { renderToString } from 'react-dom/server'
import { LoadableState } from '@loadable/server'
const loadableState = new LoadableState()
// or new LoadableState(manifest), see modes documentation
const html = renderToString(loadableState.collectChunks(<YourApp />))
const scriptTags = loadableState.getScriptTags() // or loadableState.getScriptElements();The collectChunks method wraps your element in a provider. Optionally you can use the LoadableStateManager provider directly, instead of this method. Just make sure not to use it on the client-side.
import { renderToString } from 'react-dom/server'
import { LoadableState, LoadableStateManager } from 'styled-components'
const loadableState = new LoadableState()
const html = renderToString(
<LoadableStateManager state={loadableState}>
<YourApp />
</LoadableStateManager>,
)
const scriptTags = loadableState.getScriptTags() // or loadableState.getScriptElements();The loadableState.getScriptTags() returns a string of multiple <script> tags. You must include them before your main bundle.
Alternatively the LoadableState also has a getScriptElements() method that returns an array of React elements.
loadableState.getScriptTags()andloadableState.getScriptElements()can only be called after your element is rendered. As a result, components fromloadableState.getScriptElements()cannot be combined with<YourApp />into a larger component.
Streaming rendering
Loadable is compatible with streaming rendering, if you use it you have to include script when the stream is complete.
import { renderToNodeStream } from 'react-dom/server'
import { LoadableState } from '@loadable/server'
// if you're using express.js, you'd have access to the response object "res"
// typically you'd want to write some preliminary HTML, since React doesn't handle this
res.write('<html><head><title>Test</title></head><body>')
const loadableState = new LoadableState()
// or new LoadableState(manifest), see modes documentation
const jsx = loadableState.collectChunks(<YourApp />)
const stream = renderToNodeStream(jsx)
// you'd then pipe the stream into the response object until it's done
stream.pipe(
res,
{ end: false },
)
// and finalize the response with closing HTML
stream.on('end', () =>
res.end(`${loadableState.getScriptTags()}</body></html>`),
)Streaming rendering is not compatible with prefetch
<link>tags.
Prefetching
To improve performance, you can include <link ref="preload"> in the head of your HTML page. If you use Prefetch feature of @loadable/component, you can insert them server-side.
import path from 'path'
import { LoadableState } from '@loadable/server'
// This is the manifest generated by webpack
import manifest from '../dist/loadable-manifest.json'
const loadableState = new LoadableState(manifest)
const html = renderToString(
<LoadableStateManager state={loadableState}>
<YourApp />
</LoadableStateManager>,
)
const prefetchTags = loadableState.getPrefetchTags() // or loadableState.getPrefetchElements();
const html = `<html>
<head>${prefetchTags}</head>
<body>
<div id="root">${html}</div>
</body>
</html>`It only works with
renderToStringAPI. Since<link>must be added in the<head>, you can't do it usingrenderToNodeStream.
API
LoadableState
Used to collect chunks server-side and get them as script tags or script elements.
| Arguments | Description |
|---|---|
manifest |
Optional manifest file path generated using @loadable/webpack-plugin. |
import { LoadableState } from '@loadable/server'
const loadableState = new LoadableState()
// or using manifest
const loadableState = new LoadableState(manifest)loadableState.collectChunks
Wrap your application in a LoadableManager.
| Arguments | Description |
|---|---|
element |
JSX element that will be wrapped in LoadableManager. |
const app = loadableState.collectChunks(<YourApp />)loadableState.getScriptTags
Get scripts as a string of <script> tags.
const body = `<body><div id="root">${html}</div>${loadableState.getScriptTags()}</body>`loadableState.getScriptElements
Get scripts as an array of React <script> elements.
const body = renderToString(
<body>
<div id="root" dangerouslySetInnerHtml={{ __html: html }} />
{loadableState.getScriptElements()}
</body>,
)loadableState.getPrefetchTags
Get prefetch links as a string of <link> tags.
const head = `<head>${loadableState.getPrefetchTags()}</head>`loadableState.getPrefetchElements
Get prefetch links as an array of React <link> elements.
const head = renderToString(<head>{loadableState.getPrefetchElements()}</head>)LoadableManager
Used to inject a LoadableState in the context of your application.
import { LoadableState, LoadableManager } from '@loadable/server'
const loadableState = new LoadableState()
const app = (
<LoadableManager state={loadableState}>
<YourApp />
</LoadableManager>
)License
MIT