静态网站生成
什么是静态网站生成 (SSG)?
静态网站生成器可以看作是一个脚本,它接收数据、内容和模板,对它们进行处理,并输出一个文件夹,其中包含所有结果页面和资产。
如何启用 SSG:
像这样将 export
添加到 package.json
的脚本中
"scripts": {+ "export": "razzle export",}
将 static_export.js
添加到你的 src 目录中
// ./src/static_export.jsimport { renderApp } from './server';export const render = (req, res) => { const { html } = renderApp(req, res); res.json({ html });};export const routes = () => { return ['/', '/about'];};
运行 npm export
或 yarn export
基于已构建的生产应用程序将指定路由的静态版本渲染到构建文件夹。你的预渲染应用程序已准备好提供服务!
Razzle SSG 如何工作的?
基本上,在 SSG 过程中,我们对应用程序进行 SSR,然后将 SSR 的结果保存在一个 HTML 文件中,因此,如果你启用了 SSR,你还可以拥有 SSG。
我可以将 Razzle SSG 与 X 配合使用吗?
Razzle 不仅可以与 React 配合使用,还可以与 Reason、Elm、Vue、Angular、Svelte 配合使用,最重要的是......与任何后续产品配合使用
render()
在后台,razzle 会调用从 static_export
模块公开的渲染 render
函数,并将传递给 res.json()
的 HTML 字符串保存到 HTML 文件或 req
对象中。其中唯一需要的属性是 url
,它包含要渲染并将其结果保存到 HTML 文件的 URL。HTML 文件目的地相对于 req.url
,例如,如果 URL 是 /product/A
,HTML 将保存到 /build/product/A/index.html
。
你应该在此函数中调用 renderToString()
(或框架中用于执行 SSR 的任何方法),然后将结果传递给 res.json()
export const render = (req, res) => { const html = ReactDOMServer.renderToString( <StaticRouter location={req.url}> <App /> </StaticRouter> ); res.json({ html });};
(你可以从 server.js 文件重新导出 SRR 逻辑,并将其用于 static_export
)
routes()
你还应该导出一个名为 routes
的函数,它返回一个字符串数组或一个会解析出字符串数组的 Promise。razzle 会获取这些 URL,并逐个将它们传递给 render
。你应该在此方法中从 CMS 获取应用程序的所有路径,然后返回它
export const routes = async () => { // data should be an array of strings ["/", "/product/A", "/blog/1", "/blog/2"] const { data } = await getAppPaths(); return data;};
页面数据
你可能还需要保存供页面在客户端重新水化应用程序时使用的。你可以通过 html
将 data
传递给 res.json({ html, data })
,并且 data
对象的内容将保存在 index.html
相关文件旁边的 page-data.json
中。
export const render = async (req, res) => { const data = await getDataForRoute(req.url); const html = ReactDOMServer.renderToString( <StaticRouter location={req.url}> <App /> </StaticRouter> ); res.json({ html, data });};
(注意:你应该更改应用程序在客户端获取数据的方式,以从 page-data.json
读取数据)
TypeScript 支持
静态导出开箱即用支持 TypeScript,为了使用 TypeScript,将 static_export.js
重命名为 static_export.ts
,你就可以开始了!
高级配置
// razzle.config.jsmodule.exports = { options: { staticExport: { parallel: 5, // how many pages to render at a time routesExport: 'routes', renderExport: 'render', scriptInline: false, windowRoutesVariable: 'RAZZLE_STATIC_ROUTES', windowRoutesDataVariable: 'RAZZLE_STATIC_DATA_ROUTES', }, },};