-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Umi 3 SSR & Prerender #4500
Comments
语雀复制过来格式(空行)有点乱。 |
终于迎来了更新! |
关注了好久了 |
做数据流的时候,注意下dva单例的问题,在服务端每次初始化一个dva,或者是每个请求后清空dva数据,保证每个用户得到的数据是干净的最小集,页面的体积会小点,服务器的内存也会小。期待3.0的ssr |
这个在 应用级数据 里已经考虑到了 |
发了一个 Umi 3.2.0-beta.1 版本,支持 SSR,抢先体验 Demo:https://github.com/ycjcl868/umi-ssr-demo-test |
|
能否支持基于hooks的数据流?例如hox或者unstated-next |
支持的,通过 app.ts 里暴露的:
|
可以来个 PR,这个优先级目前较低 |
现在使用umi@2的ssr遇到些框架上的问题, 期待@3.x的ssr能够解决
|
Aliyun FC 验证 ok: http://umi.ssr-fc.com/ , 对比 Umi 2,string 渲染模式下 TTFB 从 2.3s 减少到 243 ms |
基础数据会不会重新请求 谁尝试过umi3的ssr了没 |
文档中说的umi start是不是还没有实现,这个大概什么时间可以好呢? |
想了下 |
全局数据获取可以通过不同的 Layout 上的 |
Layout上有getInitialProps么 |
有的 |
I am testing 3.2.0-beta.9 version on my prod level project and have some issues using redux persist. Whenever I force load the pages, I get the following error:
One more thing, when will SSR feature be on the stable version ? |
I released the // src/app.ts
export const ssr = {
modifyGetInitialPropsCtx: async (ctx) => {
const { _store } = getApp();
ctx.store = _store;
},
} and you will get the Another thing the stable version(3.2.0) would be released in this week 🚀. |
会加在路由上 |
👍👍👍👍👍👍 |
static getInitialProps = async (ctx) => {
const res = await getStatistic({type:0, timeType:'latest1Month', ...ctx.query}, ctx.store.dispatch, ctx.history)
if(res.error){
//毫无反应是什么原因呢
ctx.history.push('/inspection')
}
return ctx.store.getState()
} 还有部署后*.css, *.js 类型都为text/html, 路径不正确 |
为啥不暴露出来呢,我感觉有些地方还是要用的。 |
[RFC] Umi 3 SSR & Prerender
背景
在 Umi 2 版本时,中途支持了 SSR 功能 #2543,有一些修改比较 hack,维护上有一定困难。与此同时,由于服务端 umi-server 与 umi 分离,用户使用门槛高,背离了 umi 开箱即用的特性。
Umi 3 发布时因时间原因,没加 SSR 功能,但与 SSR 有关的接口预留了,加上社区的催促 #4357、 dumi 静态站点、内部前台/官网项目 SEO 需求,使得现在得着手加上 服务端渲染 和 预渲染 功能。
目标
特性
import from 'umi'
的问题,服务端不会resolve
到插件导出的方法和属性。isBrowser
判断失效,带来渲染不一致问题)[id].html
文件,支持动态路由渲染。staticMarkup
配置,同时 prerender 默认使用 staticMarkup。umi.server.js
,不再需要用户手动扩展服务端,例如:getInitialProps
,通过配置app.ts
增加 getInitialProps,让全应用有公共渲染数据,不再通过 Layout 加全局数据。SSR 功能尽可能集中在 `preset-built-in/plugins/ssr.ts` 中,与正常功能解耦,**避免 SSR 强耦合 Umi 框架。**
用法
配置一行,即可开启 SSR 模式
开发
和 SPA 开发一样,然后执行
umi dev
,访问页面,就是 SSR 后的(相当于 umi-server 直接集成umi dev
中)。通过
webpack-dev-middleware
的writeToDisk
写umi.server.js
到文件系统(这里不清楚需要将writeToDisk
作为 devServer 配置中的属性不?)如果是与 Chair / Egg 集成的方式,会通过环境变量不启动内置的 dev server middleware。
全局数据
TODO
页面数据
依旧是通过
getInitialProps
,这个不变构建
执行
umi build
,除了正常的umi.js
外,会多一个 server 文件:umi.server.js
(相当于服务端入口文件,类比浏览器加载 umi.js 客户端渲染)部署
直接使用
umi start
,会默认使用 pm2 + expressjs 直接运行在生产环境。如果有单独服务端集成需求,可以单独引入
dist/umi.server.js
使用:使用内置 render:
自定义 Render(内置 string 渲染、stream 渲染,先不暴露 createServerApp):运行时增强
单独增加 prefetch(预获取) 和 preload(预加载) 插件,由用户决定是否开启:
prerender 预渲染
umi@3 使用内置的方式,不再提供
prerender
配置,通过现有的exportStatic
来做:执行
umi build
后,产物会生成所有页面的 html同时会删掉
umi.server.js
(感觉没必要再生成 服务端文件,已经渲染出来了)因为预渲染是在编译时进行,所以对于动态路由,默认只生成 SPA 的 html ,如果需要生成特定的动态路由,可以配置
extra
扩展额外的路由:实现
见 #4499 PR
流程图
ssr 和 prerender 功能都通过一个插件完成,写在
packages/preset-built-in/src/plugins/features/ssr.ts
内置插件中,作为 umi 内置功能。开发 & 构建
通过
api.chainWebpack
增加一个新 entryumi.server
,打出 commonjs2 类型。可以按 umi 2 的方式来写 umi-build-dev/src/getWebpackConfig.ts#L50-L86通过在 dev 下去增加一个
devServer
的中间件,来做服务端渲染,保证了开箱即用。数据流
直接扩展 runtime 中的 ssr:
前端框架无关
ssr.ts
插件不依赖React
、Vue
,在 Umi 中每个renderer
会提供renderClient
和renderServer
方法,分别处理客户端渲染和服务端渲染。同时还会提供
createServerElement
方法,只返回处理后的将渲染的 Element 元素(其中『处理』包括getInitialProps
处理、路由处理等)由下可知,umi.server.js 中的
render
方法,实际上是由getInitial
+
renderServer
(ReactDOM.renderToString +getServerElement
)+
handleHtml
共同组成,如果需对
render
方法进行定义,可直接基于上面的方法进行定义:如果后面需要 Vue 渲染,也可以实现:
全局变量
渲染流程:
getInitialProps
后,会将数据注入到全局变量中。getInitialProps
。umi 2 中使用了window.g_initialData
存储应用初始数据在 umi 3 中
window.g_initialData
来存储应用级初始数据window.g_initialProps
来存储页面级初始数据导出工具方法
通过
api.addUmiExports
导出isBrowser
方法,提供给开发者在getInitialProps
函数中,能够根据客户端还是服务端做不同的数据返回。预渲染
直接将 @umijs/plugin-prerender 插件融合进来,这块还好,没太大改动。
任务拆分
服务端 entry
umi.server.js
React renderServer
开发
客户端 entry
构建
部署
插件支持
相关插件:
@umijs/plugin-dva
支持 SSR 数据流 feat: support dva ssr plugins#199@umijs/plugin-helmet
支持 SSR 标题、标签渲染 feat: add helmet plugin plugins#180@umijs/plugin-model
验证@umijs/plugin-initial-state
数据流支持@umijs/plugin-locale
国际化支持预渲染
其它
TODO
window.g_initialProps
隐藏,通过黑魔法将 window.g_initialProps 脚本注入到 umi.js 中,避免 html 过多 scripts,影响百度 SEO 权重参考
The text was updated successfully, but these errors were encountered: