Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into 3.0_doc
Browse files Browse the repository at this point in the history
  • Loading branch information
zealotchen0 committed Feb 2, 2024
2 parents 0e1379e + 98df553 commit 1f47b24
Show file tree
Hide file tree
Showing 341 changed files with 20,758 additions and 2,289 deletions.
2 changes: 2 additions & 0 deletions docs/api/hippy-react/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ import icon from './qb_icon_new.png';
| supportedOrientations | 支持屏幕翻转方向 | `enum (portrait, portrait-upside-down, landscape, landscape-left, landscape-right)[]` | `iOS` |
| immersionStatusBar | 是否是沉浸式状态栏。`default: false` | `boolean` | `Android、Voltron` |
| darkStatusBarText | 是否是亮色主体文字,默认字体是黑色的,改成 true 后会认为 Modal 背景为暗色调,字体就会改成白色。 | `boolean` | `Android、iOS、Voltron` |
| autoHideStatusBar | 是否在`Modal`显示时自动隐藏状态栏。<strong>Android 中仅 api28 以上生效。</strong> `default: false` | `boolean` | `Android` |
| autoHideNavigationBar | 是否在`Modal`显示时自动隐藏导航栏。 `default: false` | `boolean` | `Android` |
| onShow |`Modal`显示时会执行此回调函数。 | `Function` | `Android、iOS、hippy-react-web、Web-Renderer、Voltron` |
| onOrientationChange | 屏幕旋转方向改变时执行会回调 | `Function` | `Android、iOS` |
| onRequestClose |`Modal` 请求关闭时会执行此回调函数,一般时在 Android 系统里按下硬件返回按钮时触发,一般要在里面处理关闭弹窗。 | `Function` | `Android、hippy-react-web、Voltron` |
Expand Down
3 changes: 3 additions & 0 deletions docs/api/hippy-vue/external-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ export default {
| supportedOrientations | 支持屏幕翻转方向 | `enum(portrait, portrait-upside-down, landscape, landscape-left, landscape-right)[]` | `iOS` |
| immersionStatusBar | 是否是沉浸式状态栏。`default: true` | `boolean` | `Android、Voltron` |
| darkStatusBarText | 是否是亮色主体文字,默认字体是黑色的,改成 true 后会认为 Modal 背景为暗色调,字体就会改成白色。 | `boolean` | `Android、iOS、Voltron` |
| autoHideStatusBar | 是否在`Modal`显示时自动隐藏状态栏。<strong>Android 中仅 api28 以上生效。</strong> `default: false` | `boolean` | `Android` |
| autoHideNavigationBar | 是否在`Modal`显示时自动隐藏导航栏。 `default: false` | `boolean` | `Android` |

| transparent | 背景是否是透明的。`default: true` | `boolean` | `Android、iOS、Web-Renderer、Voltron` |

## 事件
Expand Down
108 changes: 106 additions & 2 deletions docs/api/hippy-vue/vue3.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,106 @@ const router: Router = createRouter({
});
```

# 服务端渲染

@hippy/vue-next 现已支持服务端渲染,具体代码可以查看[示例项目](https://github.com/Tencent/Hippy/tree/main/examples/hippy-vue-next-ssr-demo)中的 SSR
部分,关于 Vue SSR 的实现及原理,可以参考[官方文档](https://cn.vuejs.org/guide/scaling-up/ssr.html)

## 如何使用SSR

请参考[示例项目](https://github.com/Tencent/Hippy/tree/main/examples/hippy-vue-next-ssr-demo)说明文档中的 How To Use SSR

## 实现原理

### SSR 架构图

<img src="assets/img/hippy-vue-next-ssr-arch-cn.png" alt="hippy-vue-next SSR 架构图" width="80%"/>

### 详细说明

@hippy/vue-next SSR 的实现涉及到了编译时,客户端运行时,以及服务端运行时三个运行环境。在 vue-next ssr的基础上,我们开发了 @hippy/vue-next-server-renderer
用于服务端运行时节点的渲染,开发了 @hippy/vue-next-compiler-ssr 用于编译时 vue 模版文件的编译。以及 @hippy/vue-next-style-parser 用于服务端渲染得到的
Native Node List 的样式插入。下面我们通过一个模版的编译和运行时过程来说明 @hippy/vue-next SSR 做了哪些事情

我们有形如`<div id="test" class="test-class"></div>`的一段模版

- 编译时

模版经过 @hippy/vue-next-compiler-ssr 的处理,得到了形如

```javascript
_push(`{"id":${ssrGetUniqueId()},"index":0,"name":"View","tagName":"div","props":{"class":"test-class","id": "test",},"children":[]},`)
```

的 render function

- 服务端运行时

在服务端运行时,编译时得到的 render function 执行后得到了对应节点的 json object。注意 render function 中的
ssrGetUniqueId 方法,是在 @hippy/vue-next-server-renderer 中提供的,在这里 server-renderer 还会对
节点的属性值等进行处理,最后得到 Native Node 的 json object

```javascript
{ "id":1,"index":0,"name":"View","tagName":"div","props":{"class":"test-class","id": "test",},"children":[] }
```

> 对于手写的非 sfc 模版的渲染函数,在 compiler 中无法处理,也是在 server-renderer 中执行的

- 客户端运行时

在客户端运行时,通过 @hippy/vue-next-style-parser,给服务端返回的节点插入样式,并直接调用 hippy native 提供的
native API,将返回的 Native Node 对象作为参数传入,并完成节点的渲染上屏。 完成节点上屏之后,再通过系统提供的
global.dynamicLoad 异步加载客户端异步版 jsBundle,完成客户端 Hydrate 并执行后续流程。

## 初始化差异

SSR 版本的 Demo 初始化与异步版的初始化有一些差异部分,这里对其中的差异部分做一个详细的说明

- src/main-native.ts 变更

1. 使用 createSSRApp 替换之前的 createApp,createApp 仅支持 CSR 渲染,而 createSSRApp 同时支持 CSR 和 SSR
2. 在初始化时候新增了 ssrNodeList 参数,作为 Hydrate 的初始化节点列表。这里我们服务端返回的初始化节点列表保存在了 global.hippySSRNodes 中,并将其作为参数在createSSRApp时传入
3. 将 app.mount 放到 router.isReady 完成后调用,因为如果不等待路由完成,会与服务端渲染的节点有所不同,导致 Hydrate 时报错

```javascript
- import { createApp } from '@hippy/vue-next';
+ import { createSSRApp } from '@hippy/vue-next';
- const app: HippyApp = createApp(App, {
+ const app: HippyApp = createSSRApp(App, {
// ssr rendered node list, use for hydration
+ ssrNodeList: global.hippySSRNodes,
});
+ router.isReady().then(() => {
+ // mount app
+ app.mount('#root');
+ });
```
- src/main-server.ts 新增
main-server.ts 是在服务端运行的业务 jsBundle,因此不需要做代码分割。整体构建为一个 bundle 即可。其核心功能就是在服务端完成首屏渲染逻辑,并将得到的首屏 Hippy 节点进行处理,插入节点属性和 store(如果存在)后返回,
以及返回当前已生成节点的最大 uniqueId 供客户端后续使用。
>注意,服务端代码是同步执行的,如果有数据请求走了异步方式,可能会出现还没有拿到数据,请求就已经返回了的情况。对于这个问题,Vue SSR 提供了专用 API 来处理这个问题:
>[onServerPrefetch](https://cn.vuejs.org/api/composition-api-lifecycle.html#onserverprefetch)。
>在 [Demo](https://github.com/Tencent/Hippy/blob/main/examples/hippy-vue-next-ssr-demo/src/app.vue) 的 app.vue 中也有 onServerPrefetch 的使用示例
- server.ts 新增
server.ts 是服务端执行的入口文件,其作用是提供 Web Server,接收客户端的 SSR CGI 请求,并将结果作为响应数据返回给客户端,包括了渲染节点列表,store,以及全局的样式列表。
- src/main-client.ts 新增
main-client.ts 是客户端执行的入口文件,与之前纯客户端渲染不同,SSR的客户端入口文件仅包含了获取首屏节点请求、插入首屏节点样式、以及将节点插入终端完成渲染的相关逻辑。
- src/ssr-node-ops.ts 新增
ssr-node-ops.ts 封装了不依赖 @hippy/vue-next 运行时的 SSR 节点的插入,更新,删除等操作逻辑
- src/webpack-plugin.ts 新增
webpack-plugin.ts 封装了 SSR 渲染所需 Hippy App 的初始化逻辑
# 其他差异说明
目前 `@hippy/vue-next``@hippy/vue` 功能上基本对齐,不过在 API 方面与 @hippy/vue 有一些区别,以及还有一些问题还没有解决,这里做些说明:
Expand Down Expand Up @@ -266,7 +366,7 @@ const router: Router = createRouter({
}
```
更多信息可以参考 demo 里的 [extend.ts](https://github.com/Tencent/Hippy/blob/master/examples/hippy-vue-next-demo/src/extend.ts).
更多信息可以参考 demo 里的 [extend.ts](https://github.com/Tencent/Hippy/blob/main/examples/hippy-vue-next-demo/src/extend.ts).
- whitespace 处理
Expand Down Expand Up @@ -305,6 +405,10 @@ const router: Router = createRouter({
`<dialog>` 组件的第一个子元素不能设置 `{ position: absolute }` 样式,如果想将 `<dialog>` 内容铺满全屏,可以给第一个子元素设置 `{ flex: 1 }` 样式或者显式设置 width 和 height 数值。这与 Hippy3.0 的逻辑保持一致。
- 书写 SSR 友好的代码
因 SSR 的渲染方式和生命周期等与客户端渲染方式有一些差异,因此需要在代码编写过程中注意,这里可以参考[Vue官方的SSR指引](https://cn.vuejs.org/guide/scaling-up/ssr.html#writing-ssr-friendly-code)
# 示例
更多使用请参考 [示例项目](https://github.com/Tencent/Hippy/tree/master/examples/hippy-vue-next-demo).
更多使用请参考 [示例项目](https://github.com/Tencent/Hippy/tree/main/examples/hippy-vue-next-demo).
Binary file added docs/assets/img/3.0-demo-create.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/3.0-demo-helloworld.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/3.0-demo-home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/3.0-demo-page-management.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/3.0-demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/img/hippy-vue-next-ssr-arch-cn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 1f47b24

Please sign in to comment.