实现 React 同构

书接上回(React 同构),之前提到这个任务迟迟未完成,影响了业务进度,所以任务重新抛了出来,虽然暂时没交过来,但未雨绸缪就改造了下之前搭建的 React 脚手架,变成了 React 脚手架-同构版

接下来聊一聊一些可能需要注意的点。

数据模型

注意区分浏览器和服务端的模型区别,在浏览器端只属于一个用户访问,但是服务端是大家都能访问,访问的又是一个地方,所以需要对每次请求生成新的实例。

// bad
let state = {};
app.get('*', (res) => {
    state.username = res.username;
})

// good
app.get('*', (res) => {
    let state = {};
    state.username = res.username;
})

全局变量

window 下的全局变量,相比大家都不陌生,常用的 location, localStorage,但要注意的是这些都属于 BOM,服务端没有这些东西,所以这些 API 需要框架注入进去。

  • 第一种解决方法是确保这些 API 在第一次渲染时不会被调用,比如可以放到 useEffect 中。
  • 第二种是通过 webpack.DefinePlugin 去注入。
  • 第三种是在 Node 中注入
    globalThis.location = {
      pathname: req.url,
    }

另外需要注意的是,新的 EcmaScript 规范中提供了 globalThis 对象,它指向了不同环境下的全局对象中的 this,即浏览器中的 windowNode 环境下的 global

WARNING: 但是更要注意的是,前端和后端的上下文,在 Node 中,globalThis 会共享到全局,所以如果 A 用户改了,B 用户会得到 A 用户修改后的结果。

导入资源

这里的资源泛指所有除 .js, .jsx 后缀的文件,比如 css-loader,这里,注意不要从服务端运行时生成文件或者插入 DOM,保留链接或者资源标识符即可。

本文链接:https://note.lilonghe.net/post/implement-isomorphic-react.html

-- EOF --