136 - 《Umi 4 的 SSR 实现》
花了好几天,终于合完 SSR 的 PR 了,趁着还热乎,做下笔记。
这个是 Todos DEMO,https://test-vercel-chencheng.vercel.app/,数据 API 基于在 herokuapp 上部署的 strapi 应用。由于免费的 herokuapp 比较慢,好久没人访问有个冷启动的过程,会超时,刷新下就好。
Umi 的 SSR 实现分 5 步,
1、生成临时文件,作为 SSR 的入口
SSR 需要一份单独的产物,用于在服务端渲染时处理请求,所以需要一个区别于 umi.ts 的不同的入口文件,这个入口文件和 umi.ts 的区别是,导出一个 request handler,用于处理请求。
export default createRequestHandler({ …args });
由于 umi 中支持在路由组件中声明 serverLoader,需要在路由组件中找出带 serverLoader exports 的组件,传给 createRequestHandler,方便在 runtime 代码中调用并返回渲染用的初始数据。
export async function serverLoader() {}
2、构建 SSR 入口文件,基于 esbuild
SSR 产物是 node 的,所以不需要处理例如补丁、语法、兼容等奇怪的问题,用 esbuild 最合适不过了,而且快。所以 Umi 4 的构建方案是 SSR esbuild,CSR webpack。
这带来几个问题,1)webpack 层实现的功能需要在 esbuild 侧也实现一遍,比如 less 编译、svg as component、mdx 等,2)esbuild 和 webpack 之间需要保持一致性,让两者串起来,我们在这部分花了很多时间,而且还没搞完。
一致性举几个例子。比如图片,webpack 打包之后在 js 里是通过 url 的方式引用,esbuild 打包时,就不需要再处理一