Skip to content

Commit 90b16cc

Browse files
feat: added loadable comnponents ssr option
1 parent 7235fdb commit 90b16cc

File tree

2 files changed

+112
-3
lines changed

2 files changed

+112
-3
lines changed

src/components/ReactCodeBlock/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const ReactCodeBlock = ({ value, linesInPrimary = [], linesInSecondary = [] }) =
3434
return {style};
3535
}}
3636
language='jsx'
37+
// TODO: delete when release
38+
// showLineNumbers
3739
style={okaidia}>
3840
{value}
3941
</SyntaxHighlighter>

src/utils/data/concepts.js

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ The code that makes up the module does not get included into the initial bundle
210210
linesInPrimary: [10, 11, 12, 13, 14]
211211
},
212212
{
213-
id: 'loadable-components-ssr',
214-
optionName: 'Loadable Components (SSR)',
213+
id: 'loadable-components',
214+
optionName: 'Loadable Components',
215215
codeSnippet:
216216
`import loadable from '@loadable/component';
217217
import Messages from './Messages';
@@ -245,11 +245,118 @@ Suspense is not available server-side and \`React.lazy\` can only work with Susp
245245
#### References:
246246
* [(Loadable Components doc) Comparison with React.lazy](https://loadable-components.com/docs/loadable-vs-react-lazy/)
247247
* [(Loadable Components doc) Error Boundaries](https://loadable-components.com/docs/error-boundaries/)
248-
* [(Loadable Components doc) Server Side Rendering](https://loadable-components.com/docs/server-side-rendering/)
249248
`,
250249
linesInPrimary: [1, 6, 7, 8, 13, 21]
251250
},
252251
{
252+
id: 'loadable-components-ssr',
253+
optionName: 'Loadable Components (SSR)',
254+
codeSnippet:
255+
`// server/index.js
256+
import express from 'express';
257+
import React from 'react';
258+
import { ChunkExtractor } from '@loadable/server';
259+
import { renderToString } from 'react-dom/server';
260+
261+
const app = express();
262+
263+
app.get('*', (req, res) => {
264+
const statsFile = path.resolve('../dist/loadable-stats.json');
265+
const extractor = new ChunkExtractor({statsFile});
266+
const jsx = extractor.collectChunks(<App />);
267+
const html = renderToString(jsx);
268+
269+
const scriptTags = extractor.getScriptTags();
270+
const linkTags = extractor.getLinkTags();
271+
const styleTags = extractor.getStyleTags();
272+
273+
res.set('content-type', 'text/html');
274+
res.send(\`
275+
<!DOCTYPE html>
276+
<html>
277+
<head>
278+
\${linkTags}
279+
\${styleTags}
280+
</head>
281+
<body>
282+
<div id='root'>\${html}</div>
283+
\${scriptTags}
284+
</body>
285+
</html>
286+
\`)
287+
});
288+
...
289+
290+
// client/index.js
291+
import React from 'react';
292+
import { hydrate } from 'react-dom';
293+
import { loadableReady } from '@loadable/component';
294+
import App from './App';
295+
296+
loadableReady(() => {
297+
const root = document.getElementById('root');
298+
hydrate(<App />, root);
299+
});
300+
301+
// client/App.js
302+
import React from 'react';
303+
import loadable from '@loadable/component';
304+
import Messages from './Messages';
305+
import MessageForm from './MessageForm';
306+
import ErrorBoundary from './ErrorBoundary';
307+
308+
const EmojiPicker = loadable(() => import('./EmojiPicker'), {
309+
fallback: <p>Loading...</p>
310+
});
311+
312+
const Chats = () => {
313+
...
314+
return (
315+
<ErrorBoundary>
316+
<div>
317+
<Messages />
318+
<MessageForm />
319+
{isEmojiPickerOpen && (
320+
<EmojiPicker />
321+
)}
322+
</div>
323+
</ErrorBoundary>
324+
);
325+
};
326+
327+
const App = () => (
328+
<div>
329+
...
330+
<Chats />
331+
</div>
332+
);
333+
334+
export default App;`,
335+
textDescription:`
336+
1. Install [@loadable/babel-plugin](https://www.npmjs.com/package/@loadable/babel-plugin) and setup \`.babelrc\` in order to transpile your server-side code.
337+
\`\`\`
338+
// .babelrc
339+
{
340+
"plugins": ["@loadable/babel-plugin"]
341+
}
342+
\`\`\`
343+
2. Install [@loadable/webpack-plugin](https://www.npmjs.com/package/@loadable/webpack-plugin) and setup \`webpack\` to generate the stats file \`loadable-stats.json\`.
344+
\`\`\`
345+
// webpack.config.js
346+
const LoadablePlugin = require('@loadable/webpack-plugin');
347+
348+
module.exports = {
349+
// ...
350+
plugins: [new LoadablePlugin()],
351+
}
352+
\`\`\`
353+
354+
#### References:
355+
* [(Loadable Components doc) Server Side Rendering](https://loadable-components.com/docs/server-side-rendering/)
356+
`,
357+
linesInPrimary: [4, 5, 10, 11, 12, 13, 15, 16, 17, 38, 39, 42, 43, 44, 45, 49, 54, 55, 56]
358+
},
359+
{
253360
id: 'import-on-visibility',
254361
optionName: 'Import on visibility',
255362
codeSnippet:

0 commit comments

Comments
 (0)