Ant-design-mobile: 是时候认真考虑一下SSR了

Created on 26 Mar 2017  ·  20Comments  ·  Source: ant-design/ant-design-mobile

随着HTTP2的到来,服务端渲染(SSR)变得更加迫切。许多原本的合并JS、合并CSS以及图片sprite技术都会换个视角重新审视。

我在尝试结合使用 next.js 和 ant-design-mobile。

过程中虽然有些周折,结果却表现的相当不错,在我看来支持SSR并非全无可能。

以下列出的组件是需要hacker手段后才能正确渲染,本来只有前6个,因为 这次提交 增加到10个。

我提议修复这10个组件并为所有WEB组件增加SSR测试代码,因为我不想看到这个项目离SSR越走越远。

不知道项目组是否愿意接受对SSR支持的PR。

Environment(required) | 环境(必填)

  • antd-mobile version(antd-mobile版本): 1.0.7
  • Browser (or mark react-native) and its version(浏览器或react-native版本):
  • Operating environment (e.g. OS name) and its version(操作系统版本或设备型号):

What did you do? Please provide steps to re-produce your problem.(请提供复现步骤)

require('enzyme').render(component)
  • [x] ListItem
  • [x] Radio
  • [x] Checkbox
  • [ ] Switch
  • [ ] Menu
  • [x] ImagePicker
  • [x] Grid
  • [x] Modal
  • [x] RefreshControl
  • [ ] SwipeAction

What do you expected?(预期的正常效果)

在服务端环境正常渲染

What happen?(发生了何种非正常现象)

找不到全局变量:window document navigator

Re-producible online demo (可复现的在线demo)

In Progress discussion

Most helpful comment

目前2.0组件均已支持SSR,本周将会发布正式版。

All 20 comments

现有的web测试代码有很多地方不支持ssr,这个有什么好的建议吗?

测试按照 antd 的方式来即可,分别在 node 和 DOM 环境下都跑一次 snapshot,保证两个环境生产的 snapshot 是一致的。

@yesmeck 现在的问题是测试代码本身就有大量引用浏览器全局变量的地方(20个.md文件)

大量修改测试代码难保不出问题。

一个一个改吧。

@yesmeck demo 除了测试目的以外,没有其他用途吧?和网站内容有没有关系?

demo 就是网站上展示的 demo。

如果是这样,那我感觉有些心有余而力不足了,demo代码中我看到有很多bugfix,不敢轻易去碰。

在所有出现 window/document/navigator 的地方,加上条件判断 typeof window !== 'undefined' && ... 这样不知道是否可行。

可以用这个 https://github.com/react-component/util#domcasusedom

不知道你说的 bugfix 是指什么。

@cncolder

建议一个一个来,我觉得最稳妥的方式是,按你实际在 ssr 应用中遇到的问题提 PR 来 fix,我们会负责review ~
有不确定的地方可以发issue 讨论。

@paranoidjk 所有的修改都是相同的问题,在我实际的 ssr 应用中我是使用相近的原理 hacker 的。

这个PR看似改动的文件很多,但这只是一个初步的更改,是在保证兼容旧版本的情况下做出的改动,只是保证服务端渲染不报错。其中一些组件需要继续讨论,避免 checksum 问题。

用 typeof 检查变量,即不影响现有的 web 代码,也不会影响 demo。

@paranoidjk got it. 🤞

当组件都支持 SSR 后,bisheng 可以开启 --ssr.

将会以服务端渲染的方式构建页面,加载速度可以更快,不过 theme 应该还需要一些调整 cc @paranoidjk

@cncolder 你好,假如我要在服务端使用antd-mobile的listView组件,那在node ./bin/www启动项目的时候就去读取reducer,cmd直接报错:Error: Cannot find module 'antd-mobile/lib/list-view/style/css'

reducer涉及到dataSource
reducer/index.js
import { ListView } from 'antd-mobile';

const dataSource = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
});

因此webpack所配置的babelrc在服务端启动的时候都无效
.babelrc
{
"presets": [ "react","es2015", 'stage-0'],
"plugins": [["import", { "style": "css", "libraryName": "antd-mobile" }]]
}

我应该怎么解决

@GZWZC 你打开 'node_modules/antd-mobile/lib/list-view/style/' 这个文件夹看一眼就明白了,那里没有 'css.js',只有个 'css.web.js'。

以目前 antd-mobile 的文件结构,你要想办法让服务端也能优先读取 '*.web.js' 才行,webpack 只能映射客户端代码中的 require

我个人使用的是 'require-hacker' :

const requireHacker = require('require-hacker')
requireHacker.resolver((filename, module) => {
  if (filename.endsWith('/style/css')) return requireHacker.resolve(`${filename}.web.js`, module)
})

@cncolder 最后完成之后, https://github.com/ant-design/antd-mobile-samples/tree/master/web-next 这个 demo 可以作为服务端渲染的指南到文档里写一句,给个链接。

mark 一下几条避免 nodejs 内存泄漏的注意事项:

目前2.0组件均已支持SSR,本周将会发布正式版。

Was this page helpful?
0 / 5 - 0 ratings