🎉 发布 Umi 3.2.0 — 可能是西湖区最好用的 SSR 框架
date
May 22, 2020
slug
umi3-ssr
status
Published
tags
Node.js
Web
React
summary
经过近一个月、256 次提交、12 个 beta 版本后,我们发布 umi 3.2.0,增加了 服务端渲染
和 预渲染 功能,可能成为西湖区最好用的 SSR(服务端渲染)研发框架。
type
Post
经过近一个月、256 次提交、12 个 beta 版本后,我们发布 umi 3.2.0,增加了 服务端渲染 和 预渲染 功能,可能成为西湖区最好用的 SSR(服务端渲染)研发框架。
如果对 SSR(服务端渲染)不熟悉,点击查看文档,了解服务端渲染解决什么问题以及在什么场景下使用。
✨ 特性
主要具备以下特性:
- 📦 开箱即用,只需一个配置,即可开发、部署 SSR 应用
- 🌈 框架无关,不依赖于后端框架,可无缝运行在主流 Node.js、Serverless 框架中
- 🚀 流式渲染,一键开启流式渲染,减少 TTFB(Time To First Byte)
- 🔥 热更新支持,开发环境下支持代码热更新,所见即所得
- 🎊 动态加载,支持客户端开启动态加载,对应页面输出相应资源
- 🎁 数据预获取,Layout 支持数据预获取
- 💄 预渲染支持,适用无后端服务器场景,预渲染在构建时将页面 HTML 生成,同时支持动态路由生成
- ⬇️ 降级处理,服务端渲染出错后,自动降级为客户端渲染,不影响整体渲染
- ♻️ 生态支持,插件如 dva、dumi 已支持 SSR,插件只需一个 API 即支持 SSR
快速开始
先找个地方建个空目录,并初始化一个 umi 项目,安装依赖
$ mkdir myapp && cd myapp $ yarn create @umijs/umi-app # 或 npx @umijs/create-umi-app $ yarn # 或 npm install
开启 ssr 配置,更多配置见这里
// .umirc.ts import { defineConfig } from 'umi'; export default defineConfig({ + ssr: {}, nodeModulesTransform: { type: 'none', }, routes: [{ path: '/', component: '@/pages/index' }], });
启动项目
$ yarn start Starting the development server... ✔ Client Compiled successfully in 2.75s ✔ Server Compiled successfully in 2.95s DONE Compiled successfully in 17842ms 8:06:31 PM App running at: - Local: http://localhost:8000 (copied to clipboard) - Network: http://192.168.12.34:8000 [SSR] render / start: 69.142ms [SSR] render / start: 61.793ms
在浏览器里打开 http://localhost:8000/,即是服务端渲染后的页面

若需要部署,执行
umi build
,默认会生成 dist/umi.server.js
,在主流 Node.js / Serverless 框架中使用const render = require('./dist/umi.server'); const { html, error } = await render({ // 对应后端框架的 path/url // 例如 ctx.path(Koa)、req.url(Express)、ctx.request.url(Egg.js) path: '/', });
例如部署在阿里云函数计算中的 Umi 3 SSR

性能提升
相较于 Umi 2 SSR,渲染性能近一倍提升,TTFB 是之前的一半

如果对首屏加载时间需求强烈,可开启流式渲染,减少 TTFB:
export default { ssr: { // 默认为 string + mode: 'stream', }, }
预渲染
Umi 3 没有对预渲染没有增加新配置项,只需要在
ssr
配置开启情况下,开启 exportStatic
配置即可// .umirc.ts import { defineConfig } from 'umi'; export default defineConfig({ ssr: {}, + exportStatic: {}, nodeModulesTransform: { type: 'none', }, routes: [{ path: '/', component: '@/pages/index' }], });
执行
umi build
,会将页面里的内容渲染到 HTML 中$ umi build ✔ Client Compiled successfully in 7.35s ✔ Server Compiled successfully in 6.96s INFO /index.html render success INFO / render success DONE Compiled successfully in 7356ms

同时预渲染支持动态路由生成,只需要配置
export default { ssr: {}, exportStatic: { + extraRoutePaths: async () => { + const ids = await request('/api/ids'); + return ids.map(path => `/news/${id}`); + } } }
执行
umi build
即可生成
生态支持
如果你在使用 dumi 写组件或文档,建议开启预渲染,这将有利于文档站点的 SEO、开发出来的组件库天然兼容 SSR 。
// .umirc.ts export default { + ssr: {}, + exportStatic: {}, mode: 'site', }
例如使用 dumi 构建的 umi 官网

对于 umi 生态中的插件集 @umijs/preset-react,已支持 dva 和 helmet 服务端渲染,这将有助于服务端应用中的数据流管理和文档头生成。
安装
$ yarn add @umijs/preset-react
dva 支持,加载 dva 插件后,会在每个 getInitialProps 函数的 ctx 参数中注入
store
参数,根据需要返回页面初始化数据// pages/Home.tsx const Home = () => { return ( ... ) } Home.getInitialProps = async (ctx) => { const { store } = ctx; return store.getState(); }
标题渲染
// pages/Home.tsx import { Helmet } from 'umi'; export default () => ( <> <Helmet> <title>Title Helmet</title> </Helmet> </> )
执行渲染,HTML 中会返回渲染好的标题 title。
如果有插件需要支持 SSR,只需扩展一个运行时 API,即可支持。