我有一个Gatsby网站,其中包含一个名为ArticleBody
的React组件,该组件使用react-markdown将用Markdown编写的文章转换为React树。
由于这是一个昂贵的操作,并且组件有点大(出于SEO的原因),我想在构建时预渲染ArticleBody
。但是,我也想在客户端中异步加载ArticleBody
。由于文章正文已经包含在HTML中,因此不必急于在客户端中加载和呈现Markdown组件,因此异步就可以了。
我该怎么做?几乎就像我想拥有两个不同的JS捆绑包一样:一个捆绑包为构建同步加载ArticleBody
,而另一个捆绑包为客户端异步加载。在盖茨比有可能吗?
谢谢!
答案 0 :(得分:1)
您可以使用可加载组件代替不支持的 React.lazy。有一个 Gatsby 插件可以正确处理 SSR gatsby-plugin-loadable-components-ssr
自 Gatsby 3.x 以来,目前存在一个问题,但有一种方法可以在没有额外插件的情况下自行实现。请参阅问题 here 中的评论。还要添加其下方评论中提到的更改。
我还没有尝试过这个特定的实现,但它应该可以通过以下步骤工作:
npm install --save-dev @loadable/babel-plugin @loadable/server @loadable/webpack-plugin @loadable/component
gatsby-browser.js
import { loadableReady } from '@loadable/component'
import { hydrate } from 'react-dom'
export const replaceHydrateFunction = () => (element, container, callback) => {
loadableReady(() => {
hydrate(element, container, callback)
})
}
gatsby-node.js
exports.onCreateWebpackConfig = ({ actions, stage }) => {
if (
stage === "build-javascript" ||
stage === "develop" ||
stage === "develop-html"
) {
actions.setWebpackConfig({
plugins: [
new LoadablePlugin({
filename:
stage === "develop"
? `public/loadable-stats.json`
: "loadable-stats.json",
writeToDisk: true
})
]
});
}
};
gatsby-ssr.js
import { ChunkExtractor } from '@loadable/server'
import path from 'path'
const extractor = new ChunkExtractor({
// Read the stats file generated by webpack loadable plugin.
statsFile: path.resolve('./public/loadable-stats.json'),
entrypoints: [],
})
// extractor.collectChunks() will wrap the application in a ChunkExtractorManager
export const wrapRootElement = ({ element }) =>
extractor.collectChunks(element)
export const onRenderBody = ({ setHeadComponents, setPostBodyComponents }) => {
// Set link rel="preload" tags in the head to start the request asap. This will NOT parse the assets fetched
setHeadComponents(extractor.getLinkElements())
// Set script and style tags at the end of the document to parse the assets.
setPostBodyComponents([...extractor.getScriptElements(), ...extractor.getStyleElements()])
// Reset collected chunks after each page is rendered
extractor.chunks = []
}
如果您启用了 DEV_SSR,则不应添加 stage === "develop-html"。否则,你很好。
希望这个问题评论的摘要可以帮助您入门。