surmon-china / surmon.me

🌱 My digital garden, powered by myself.
https://surmon.me
MIT License
2.1k stars 596 forks source link

[求助]: 我想请问下源码中`renderSripts`部分的作用 #218

Closed nonzzz closed 2 years ago

nonzzz commented 2 years ago

Description

大佬,我在翻阅源码的时候,注意到了这么一个函数,函数包裹了2个子函数分别是renderSSRSymbleScriptrenderSSRContextScript,但是我并没有理解他们2个的作用是什么。对此感到疑惑。希望能得到大佬的帮助。

nonzzz commented 2 years ago

也许我大致知道了,是为了同步globalState的状态?

surmon-china commented 2 years ago

@XeryYue

首先在 SSR 应用中,SSR > CSR (hydrate) 这个阶段是需要通过 HTML.script 传递状态的,别无他法。

简单说就是,你需要 SSR 在服务端渲染好 HTML 片段之后,在吐给客户端的过程中,把 SSR 渲染时用到的数据一并带上返回给客户端,客户端收到数据和渲染好的 HTML 后进行 hydrate,这样客户端就避免了重新请求数据(refetch)和重新渲染应用(rerender)同时保证了 SSR 与 CSR 渲染结果的一致性,不然的话你可以试试把这些逻辑去掉,你会发现客户端 mount 时会 “闪屏”。

而这个传递数据的过程,只有用 <script>window._SSR_JSON_ = {}</script> 是最合适的,这就是 renderSripts 做的事。

你可以按顺序参考这些文档:

  1. https://vitejs.dev/guide/ssr.html
  2. https://pinia.vuejs.org/ssr/#state-hydration

renderSripts 具体要传递哪些 “状态”,取决于你的业务需求,很明显,在 surmon.me 项目中,我需要传递 这些状态

  1. pinia store
  2. globalState
  3. metas
  4. url
  5. layout
  6. theme
  7. 等等...

如此问题就被简化为,为啥我用了 ssrContextScript ssrSymbleScript 两个标识来传递两个数据?

ssrContextScript 其实就是 “上下文”,也就是那些 SSR 模式下需要真实传递给客户端的状态数据,也就是上文 2 中提到的那些东西,技术本质就是一个大的序列化过的 JSON 对象。

但 surmon.me 是支持 SPA 和 SSR 两种开发、运行模式的,在 SPA 运行模式下,ssrContextScript 会是不存在的, 所以我们需要 另外一个标识 来告诉客户端 “当前是不是 SSR 模式”,如果不是的话,不要执行 hydrate 渲染,使用正常的 SPA 模式渲染即可


所以,如果你是一个纯粹的 SSR 应用或 SPA 应用,你都应该会有自己确定的逻辑,你都不需要 ssrSymbleScript 的存在,而不必像 surmon.me 这个项目做过多的兼容处理。

nonzzz commented 2 years ago

ssrSymbleScrip

感谢大佬的解惑。