From 6a8ee224fb4c590d9d49d2ce59035f0273f3f3c7 Mon Sep 17 00:00:00 2001 From: lzxb Date: Fri, 1 Nov 2024 19:27:36 +0800 Subject: [PATCH] deploy --- .DS_Store | Bin 0 -> 6148 bytes 404.html | 17 ++ guide/essentials/alias.html | 45 ++++ guide/essentials/command.html | 78 +++++++ guide/essentials/module-link.html | 225 +++++++++++++++++++ guide/index.html | 45 ++++ guide/senior/module-link.html | 17 ++ guide/start/getting-started.html | 124 ++++++++++ hello.html | 19 ++ index.html | 17 ++ logo.svg | 3 + static/css/styles.03ffc65a.css | 1 + static/js/async/191.0033d0fb.js | 1 + static/js/async/418.60ed0315.js | 1 + static/js/async/512.8135c617.js | 1 + static/js/async/52.3753b1a1.js | 1 + static/js/async/659.7d61eb15.js | 1 + static/js/async/80.7b303c6c.js | 1 + static/js/async/885.950c6999.js | 1 + static/js/async/889.8e5ff8e9.js | 1 + static/js/index.7fbae4e3.js | 6 + static/js/index.7fbae4e3.js.LICENSE.txt | 35 +++ static/js/lib-react.ec5ef4c6.js | 2 + static/js/lib-react.ec5ef4c6.js.LICENSE.txt | 39 ++++ static/js/lib-router.ab7f2709.js | 2 + static/js/lib-router.ab7f2709.js.LICENSE.txt | 32 +++ static/js/styles.2cea1366.js | 1 + static/search_index.c1c19676.json | 1 + 28 files changed, 717 insertions(+) create mode 100644 .DS_Store create mode 100644 404.html create mode 100644 guide/essentials/alias.html create mode 100644 guide/essentials/command.html create mode 100644 guide/essentials/module-link.html create mode 100644 guide/index.html create mode 100644 guide/senior/module-link.html create mode 100644 guide/start/getting-started.html create mode 100644 hello.html create mode 100644 index.html create mode 100644 logo.svg create mode 100644 static/css/styles.03ffc65a.css create mode 100644 static/js/async/191.0033d0fb.js create mode 100644 static/js/async/418.60ed0315.js create mode 100644 static/js/async/512.8135c617.js create mode 100644 static/js/async/52.3753b1a1.js create mode 100644 static/js/async/659.7d61eb15.js create mode 100644 static/js/async/80.7b303c6c.js create mode 100644 static/js/async/885.950c6999.js create mode 100644 static/js/async/889.8e5ff8e9.js create mode 100644 static/js/index.7fbae4e3.js create mode 100644 static/js/index.7fbae4e3.js.LICENSE.txt create mode 100644 static/js/lib-react.ec5ef4c6.js create mode 100644 static/js/lib-react.ec5ef4c6.js.LICENSE.txt create mode 100644 static/js/lib-router.ab7f2709.js create mode 100644 static/js/lib-router.ab7f2709.js.LICENSE.txt create mode 100644 static/js/styles.2cea1366.js create mode 100644 static/search_index.c1c19676.json diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + + + + + + 404 - Gez + + + +

404

PAGE NOT FOUND

+
+ + + diff --git a/guide/essentials/alias.html b/guide/essentials/alias.html new file mode 100644 index 00000000..ea6d1344 --- /dev/null +++ b/guide/essentials/alias.html @@ -0,0 +1,45 @@ + + + + + + + + + 别名 - Gez + + + +

别名

+

在 Gez 中,默认使用服务名来作为别名,这样有两个好处。

+
    +
  • 在调用其它服务时保持命名风格的统一
  • +
  • 执行 npm run build:dts 命令,生成的类型可以被其它服务使用。
  • +
+

entry.node.ts

+
import type { GezOptions } from '@gez/core';
+
+export default {
+    name: 'ssr-module-auth'
+} satisfies GezOptions;
+

程序会读取这里的 name 配置,设置别名为 ssr-module-auth

+

tsconfig.json

+

同时还需要在 tsconfig.json 配置别名。

+
{
+    "compilerOptions": {
+        "paths": {
+            "ssr-rspack-vue2/src/*": [
+                "./src/*"
+            ],
+            "ssr-rspack-vue2/*": [
+                "./*"
+            ]
+        }
+    }
+}
+
TIP

如果你想了解多服务类型如何工作的,可以了解一下 gez release 命令的说明。 +

+
+ + + diff --git a/guide/essentials/command.html b/guide/essentials/command.html new file mode 100644 index 00000000..ad62269b --- /dev/null +++ b/guide/essentials/command.html @@ -0,0 +1,78 @@ + + + + + + + + + 命令 - Gez + + + +

命令

+

一个典型的命令配置。

+
{
+    "scripts": {
+        "dev": "gez dev",
+        "build": "npm run build:ssr && npm run build:dts && npm run release",
+        "build:ssr": "gez build",
+        "build:dts": "vue-tsc --declaration --emitDeclarationOnly --noEmit false --outDir dist/server/src",
+        "release": "gez release",
+        "preview": "gez preview",
+        "start": "gez start",
+        "postinstall": "gez install"
+    }
+}
+

gez dev

+

本地开发时启动。

+
TIP

如果链接的服务是一个本地的目录,你也可以把该服务跑起来快速的开发调试。

+
export default {
+    name: 'ssr-module-auth',
+    modules: {
+        imports: {
+            'ssr-core': 'root:../ssr-core/dist'
+        }
+    }
+} satisfies GezOptions;
+

gez build

+

构建生产代码

+
TIP

有三个产物,分别是 client、server、node。

+

gez release

+

当前服务如果有对外导出模块时使用。

+
    +
  • 执行 gez build 命令,构建生产产物。
  • +
  • 执行 npm run build:dts 命令,将类型输出到 dist/server/src 目录,本地开发时,可以得到类型提示。
  • +
  • 执行 gez release 命令,将 dist/clientdist/server 目录生成 zip 压缩文件,放到 dist/client/versions 目录中。
  • +
  • dist 目录的代码,部署到生产环境中。
  • +
  • 其它服务调用 +
      +
    • entry.node.ts 配置 +
      export default {
      +    name: 'ssr-module-auth',
      +    modules: {
      +        imports: {
      +            'ssr-core': ['root:../ssr-core/dist', 'https://<hostname>/ssr-core/versions/latest.json']
      +        }
      +    }
      +} satisfies GezOptions;
      +
    • +
    • 执行 npm install 命令,触发 postinstall 钩子,再执行 gez install 命令下载
    • +
    +
  • +
+
TIP

可以封装一个 build 命令,将多个命令封装到一起。 +

+

gez preview

+

等同于执行 gez build && gez start

+

gez start

+

运行生产环境代码

+
TIP

开发环境中,所依赖的外部服务代码变更,总是会获得热更新,但是在生产环境中是没有热更新的。

如果依赖的服务发布更新了,你需要手动重启一下服务,或者编写一个脚本,监听版本发布来重启服务。

+

gez install

+

安装远程依赖到本地

+
TIP

postinstall 钩子中,执行 npm install --production 安装生产依赖无效。 +

+
+ + + diff --git a/guide/essentials/module-link.html b/guide/essentials/module-link.html new file mode 100644 index 00000000..81bacf38 --- /dev/null +++ b/guide/essentials/module-link.html @@ -0,0 +1,225 @@ + + + + + + + + + 模块链接 - Gez + + + +

模块链接

+

一个大型项目,总是会拆分成组件库、工具库、业务模块等。它们总是会写在不同的地方,以独立的仓库、monorepo 包等形式存在,但是最终都需要系统的主程序链接这些模块。Gez 的核心功能就是帮你把这些不同地方的模块,快速的链接到一起。实现一个服务发布,其它服务同时更新。

+
TIP

Gez 默认是支持 SSR 的,你也可以把它当成 CSR 来使用。

+

设计理念

+
    +
  • 我们应该设计一个基础服务,由基础服务提供所有的第三方依赖。
  • +
  • 基础服务统一维护第三方依赖更新,一次发布,所有业务系统生效。
  • +
  • 业务服务仅构建业务代码,所有的第三方依赖,应指向到基础服务中。
  • +
+
TIP

由于第三方依赖,都被指向到了基础服务,不再需要重复打包,这会让 Rspack 的编译速度,再提升一个台阶。

+

构建

+

传统的 SSR 程序在构建目标为 node 时,会将 node_modules 的模块设置为外部依赖,但是 Gez 会把全部代码都打包成 ESM 模块来进行链接。所以在使用一些第三方依赖的时候,尽可能的选择支持 ESM 的包,否则你可能会遇到一些问题。 +构建完成后,通常你可以看到这样的目录结构。

+
- dist/ # 构建输出目录 + - client/ # 客户端构建输出 + - chunks/ # 当前服务抽离的公共代码 + - [name].[contenthash].js + - npm/ # 对外导出的 node_modules 包 + - [name].[contenthash].js + - src/ # 对外导出的 src 目录下的文件 + - [name].[contenthash].js + - versions/ # 执行 gez release 命令,会将 client 和 server 的代码打包到这里 + - [contenthash].zip # 压缩文件 + - [contenthash].json # 当前压缩的版本号 + - latest.json # 最新的版本号 + - entry.[contenthash].js # 入口文件 + - importmap.js # 不可缓存文件,执行后往 globalThis 注入 __importmap__ + - importmap.[contenthash].js # 可缓存文件,执行后往 globalThis 注入 __importmap__ + - package.json # 声明模块的基本导出信息 + - server/ # 服务端构建输出 + - ... # 除了缺少 versions 目录,其它和 client 目录一致 +
+
TIP

使用 [contenthash] 可以让我们生成基于内容哈希的文件名,这样我们的静态资产文件就可以放心的设置为强缓存了。
+

+

客户端链接

+

在服务渲染时注入所有服务的 /[服务名]/importmap.[contenthash].js 文件,将模块的哈希映射信息写入到 globalThis.__importmap__ 对象中,最终将该变量值写入到 <script type="importmap"></script> 标签中。

+

src/entry.server.ts

+
import type { ServerContext } from '@gez/core';
+
+export default async (ctx: ServerContext, params: { url: string }) => {
+    const script = await ctx.getInjectScript();
+    ctx.html = `
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Gez</title>
+</head>
+<body>
+    ${script}
+</body>
+</html>
+`;
+};
+

客户端渲染

+
TIP
+
    +
  • package.json 中有一个 hash 字段,等同于 importmap.[contenthash].js 文件的哈希值。
  • +
  • 如果你只想做客户端渲染,可以编写一个脚本,读取每个服务的 dist/client/package.json 来生成一个静态的 index.html。可以参考一下 ServerContext 的实现。
  • +
+
+

服务端链接

+

src/entry.node.ts

+
    +
  • +

    在开发阶段时,我们可以设置一个远程的依赖地址。

    +
  • +
  • +

    程序会根据你配置的本地路径,计算出一个所有服务可以共同访问的 node_modules 路径,并自动创建软链接。

    +
  • +
+
export default {
+    name: 'ssr-module-auth',
+    modules: {
+        imports: {
+            'ssr-base': ['root:../ssr-base/dist', 'https://<hostname>/ssr-base/versions/latest.json']
+        }
+    }
+} satisfies GezOptions;
+
WARNING

在生产环境中,你应该使用本地链接,而不是远程链接,这样能提高应用程序的启动速度。如果你使用 Docker,可以通过使用持久卷,将不同服务的产物组织到一个目录中。 +

+

package.json

+

配置 postinstall 钩子执行 gez install 命令。在安装开发依赖时,就会将远程依赖下载到你配置的 'root:../ssr-base/dist' 目录中。

+
"scripts": {
+    "postinstall": "gez install"
+}
+
WARNING

这个需要在构建时,提供对应的版本才能下载。更多请查看 gez release 命令说明。 +

+

示例

+

ssr-base

+

基础服务,提供了所有的第三方依赖和基础组件。

+

src/entry.node.ts

+
export default {
+    name: 'ssr-base',
+    modules: {
+        exports: [
+            'root:src/components/layout.vue',
+            'root:src/utils/index.ts',
+            'npm:vue',
+            'npm:vue-router'
+        ]
+    }
+} satisfies GezOptions;
+
WARNING

如果一个依赖包,只在 SSR 中使用,那么你应该总是将它放到开发依赖中,这样能显著减少安装生产依赖的大小。

+

导出类型

+
    +
  • 使用方式 +
      +
    • 在其它的服务的 src/entry.node.ts 文件中的 modules.imports 配置添加 ssr-base
    • +
    +
  • +
  • root: +
      +
    • 配置项目文件路径,通常是 src 目录的。
    • +
    • 例如: +
        +
      • import Layout from 'ssr-base/src/components/layout.vue'
      • +
      • import utils from 'ssr-base/utils/index'
      • +
      +
    • +
    +
  • +
  • npm: +
      +
    • 指向的是当前项目的依赖包,通常是 package.json 字段中 devDependencies 配置的依赖名。
    • +
    • 需要配置 modules.externals,将对应的依赖名,指向到 ssr-base/npm/包名
    • +
    +
  • +
+

多版本依赖共存

+

package.json 中配置别名。

+
{
+    "dependencies": {
+        "query-string5": "npm:query-string@^5.1.1",
+        "query-string6": "npm:query-string@^6.11.1"
+    }
+}
+

src/entry.node.ts 文件中配置对外导出。

+
export default {
+    name: 'ssr-base',
+    modules: {
+        exports: [
+            // ...
+            'npm:query-string5', // 模块链接:ssr-base/npm/query-string5
+            'npm:query-string6'  // 模块链接:ssr-base/npm/query-string6
+        ]
+    }
+} satisfies GezOptions;
+

在对应的服务将 query-string 模块链接到你需要的版本。

+

ssr-module-auth

+

将登录、注册、验证码、修改密码、找回密码等用户信息认证的业务单独在一个服务中实现,对外导出相关的页面路由地址。

+

src/entry.node.ts

+
export default {
+    name: 'ssr-module-auth',
+    modules: {
+        // 其它服务使用:import routes from 'ssr-module-auth/src/routes
+        exports: ['root:src/routes.ts'],
+        // 总是需要配置依赖服务的地址
+        imports: {
+            'ssr-base': 'root:../ssr-base/dist'
+        },
+        // 这里只配置链接的第三方依赖,实现依赖共享
+        externals: {
+            vue: 'ssr-base/npm/vue',
+            'vue-router': 'ssr-base/npm/vue-router'
+        }
+    }
+} satisfies GezOptions;
+
TIP
+
    +
  • 当我们开发一个很大的系统时,可以按照业务模块来划分不同的服务,明确每个服务的职责。
  • +
  • 当你将第三方依赖全部指向到 ssr-base 服务时,项目构建速度总是会非常快,基本上都能在瞬间完成。
  • +
+
+

ssr-main

+

系统的主程序,负责将不同的业务服务,链接到一起。

+

src/entry.node.ts

+
export default {
+    name: 'ssr-main',
+    modules: {
+        imports: {
+            'ssr-base': 'root:../ssr-base/dist',
+            'ssr-module-auth': 'root:../ssr-module-auth/dist'
+        },
+        externals: {
+            vue: 'ssr-base/npm/vue',
+            'vue-router': 'ssr-base/npm/vue-router'
+        }
+    }
+} satisfies GezOptions;
+

使用方式

+
    +
  • import Layout from 'ssr-base/src/components/layout.vue' +
      +
    • 调用 ssr-base 服务的路由配置文件
    • +
    +
  • +
  • import routes from 'ssr-module-auth/src/routes +
      +
    • 调用 ssr-module-auth 服务的路由配置文件
    • +
    +
  • +
  • import Vue from 'vue' +
      +
    • 构建工具会替换为 import Vue from 'ssr-base/npm/vue'
    • +
    • 其它依赖举一反三
    • +
    +
  • +
+

总结

+
+ + + diff --git a/guide/index.html b/guide/index.html new file mode 100644 index 00000000..952ff5f0 --- /dev/null +++ b/guide/index.html @@ -0,0 +1,45 @@ + + + + + + + + + 介绍 - Gez + + + +

介绍

+

Gez 是 Genesis 迭代的第三个大版本,v1.0 是通过 HTTP 请求来实现的远程组件,v2.0 是通过 Module Federation v1.0 +实现的远程组件。随着主流浏览器都已经支持 ESM,这使得设计一款基于 ESM 的模块链接变成了可能。随着 Rspack v1.0 的发布,提供了对 ESM 更加友好的支持,这使得我们可以将可能变成了现实。于是,我们将 v3.0 版本重命名为 Gez

+

为什么选 Gez

+

目前社区类微服务的解决方案基本可以分为 iframe、micro-app、module federation 三种代表。其中 iframe 和 micro-app 这种模式只适合对已有的老项目进行缝合,是以降低程序运行效率所做的一种妥协,而 module federation 的接入成本较高,里面又是一个黑盒子,一旦出了问题,都十分难以排查。

+

Gez 完全是基于 ESM 模块系统进行设计,默认支持 SSR,每个服务都可以对外导出模块,也可以使用外部模块,整个过程简单透明,能够精准的控制依赖管理。通过 importmap 将多服务的模块映射到具有强缓存,基于内容哈希的 URL 中

+

调研

+
    +
  • 参考了 Vite 对现代 JavaScript 支持的定义,以浏览器支持 ESM dynamic importimport.meta 作为基准 +
      +
    • Chrome >=87
    • +
    • Firefox >=78
    • +
    • Safari >=14
    • +
    • Edge >=88
    • +
    • node >=20
    • +
    +
  • +
  • 构建出具有内容哈希的产物,使用 importmapimport vue from 'vue' 替换成 ssr-npm/npm/vue.[contenthash].js,这样静态文件就可以设置为强缓存了。对于不支持 importmap 的浏览器,es-module-shims 提供了降级的方案
  • +
  • Rspack 的 externalsType 支持使用 module-import,来设置 ESM 模块的外部依赖。
  • +
  • 在 Node 上实现 ESM 模块热更新不是一件容易的事情,庆幸的是可以通过启用 node --experimental-vm-modules --experimental-import-meta-resolve 来实现它。
  • +
  • 最终确定使用 Rspack 和 Node20 来实现 v3.0 版本。
  • +
+
TIP

从最早的构思,到开始调研 Vite、Rspack,中间经历了一年多的时间,庆幸的是这条路最终走通了,并且达到了生产可用。

+

定位

+

Gez 的定位并不是成为 Next.jsNuxt.js 那样大而全的框架,而是成为一个具有 Typescript、ESM、SSR、模块链接等特性的基础设施,你可以在这个基础上来构建属于你自己的 Next.js。如果你需要定制化实现,它会很适合你。

+

兼容性

+

所有的主流浏览器都已经支持,针对一些低版本的浏览器,可以提供一个升级的页面来引导用户升级它的浏览器。

+

可靠性

+

v1.0v2.0 到现在的 v3.0,已经走过了将近 5 年的时光,支持起了公司内部数十个业务的项目,并且不断地推动业务项目的升级。

+
+ + + diff --git a/guide/senior/module-link.html b/guide/senior/module-link.html new file mode 100644 index 00000000..9321e4e8 --- /dev/null +++ b/guide/senior/module-link.html @@ -0,0 +1,17 @@ + + + + + + + + + 模块链接实现原理 - Gez + + + +

模块链接实现原理

+
+ + + diff --git a/guide/start/getting-started.html b/guide/start/getting-started.html new file mode 100644 index 00000000..79cafbf4 --- /dev/null +++ b/guide/start/getting-started.html @@ -0,0 +1,124 @@ + + + + + + + + + 快速开始 - Gez + + + +

快速开始

+

这是一个与框架无关的例子,采用原生的 HTML 来开发项目

+

创建项目

+
cd 项目目录
+npm init
+

将项目设置为 module

+

package.json 文件添加

+
{
+    "type": "module"
+}
+

安装依赖

+
TIP

总是应该将生产依赖和开发依赖区分,会使 node_modules 在生产环境中更小。 +

+

安装生产依赖

+
npm
yarn
pnpm
bun
npm install @gez/core
+

安装开发依赖

+
npm
yarn
pnpm
bun
npm install @gez/rspack -D
+

添加脚本

+

package.json 文件添加

+
{
+  "scripts": {
+    "dev": "gez dev",
+    "build": "gez build",
+    "start": "gez start",
+    "preview": "gez preview",
+    "release": "gez release",
+    "postinstall": "gez install"
+  }
+}
+

入口文件

+

基本结构

+
- src/ + - entry.client.ts # 客户端程序入口,一般会处理水合 + - entry.server.ts # 使用框架的 SSR API 渲染出 HTML 内容 + - entry.node.ts # 创建一个服务器程序,来处理请求 +
+

src/entry.client.ts

+

模拟水合,更新当前时间

+
const time = document.querySelector('time');
+setInterval(() => {
+    time?.setHTMLUnsafe(new Date().toISOString());
+}, 1000);
+

src/entry.server.ts

+

模拟框架的 SSR API,渲染出 HTML 内容返回

+
// 这里必须使用 import type,否则开发阶段会报错
+import type { ServerContext } from '@gez/core';
+
+export default async (ctx: ServerContext, params: { url: string }) => {
+    // 获取注入的代码
+    const script = await ctx.getInjectScript();
+    const time = new Date().toISOString();
+    ctx.html = `
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Gez</title>
+</head>
+<body>
+    <h1>Gez</h1>
+    <h2>Hello world!</h2>
+    <p>URL: ${params.url}</p>
+    <time>${time}</time>
+    ${script}
+</body>
+</html>
+`;
+};
+

src/entry.node.ts

+

创建一个 web 服务器,来处理客户请求

+
import http from 'node:http';
+import type { GezOptions } from '@gez/core';
+
+export default {
+    // 设置应用的唯一名字,如果有多个项目,则名字不能重复
+    name: 'ssr-html',
+    // 本地执行 dev 和 build 时会使用
+    async createDevApp(gez) {
+        return import('@gez/rspack').then((m) =>
+            m.createApp(gez, (buildContext) => {
+                // 可以在这里修改 Rspack 编译的配置
+            })
+        );
+    },
+    async createServer(gez) {
+        const server = http.createServer((req, res) => {
+            // 静态文件处理
+            gez.middleware(req, res, async () => {
+                // 传入渲染的参数
+                const ctx = await gez.render({
+                    url: req.url
+                });
+                // 响应 HTML 内容
+                res.end(ctx.html);
+            });
+        });
+        // 监听端口
+        server.listen(3005, () => {
+            console.log('http://localhost:3005');
+        });
+    }
+} satisfies GezOptions;
+

启动项目

+
npm run dev
+
+

浏览器打开:http://localhost:3005

+
+
+ + + diff --git a/hello.html b/hello.html new file mode 100644 index 00000000..8722a79c --- /dev/null +++ b/hello.html @@ -0,0 +1,19 @@ + + + + + + + + + Hello World! - Gez + + + +

Hello World!

+

Start

+

Write something to build your own docs! 🎁

ON THIS PAGE
+
+ + + diff --git a/index.html b/index.html new file mode 100644 index 00000000..f93a4ef0 --- /dev/null +++ b/index.html @@ -0,0 +1,17 @@ + + + + + + + + + Gez + + + +

Gez

基于 ESM 的模块链接。

👍

技术创新

首个基于 ESM 构建的 SSR 多服务模块链接。

🚀

项目构建

基于 Rspack 实现,构建速度极快,带给你极致的开发体验。

🎯

依赖管理

一次构建,一次发布,多服务生效。

☁️

同构渲染

支持 Vue2、Vue3、React 等不同框架实现 SSR。

😎

基准支持

Node20 和支持 ESM dynamic import 和 import.meta 的浏览器。

👏

长久维护

Genesis 从 2020 年迭代至今,现更名为 Gez。

+
+ + + diff --git a/logo.svg b/logo.svg new file mode 100644 index 00000000..fef098a6 --- /dev/null +++ b/logo.svg @@ -0,0 +1,3 @@ + + Gez + \ No newline at end of file diff --git a/static/css/styles.03ffc65a.css b/static/css/styles.03ffc65a.css new file mode 100644 index 00000000..1f65d8c6 --- /dev/null +++ b/static/css/styles.03ffc65a.css @@ -0,0 +1 @@ +.medium-zoom-overlay,.medium-zoom-image--opened{z-index:999}:root{--rp-nav-height:72px;--rp-sidebar-width:320px;--rp-aside-width:268px;--rp-c-bg:#fff;--rp-c-bg-soft:#f9f9f9;--rp-c-bg-mute:#f1f1f1;--rp-c-divider:#3c3c3c4a;--rp-c-divider-light:#3c3c3c1a;--rp-c-text-1:#213547;--rp-c-text-2:#3c3c3ca8;--rp-c-text-3:#3c3c3c54;--rp-c-text-4:#3c3c3c2e;--rp-c-text-code:#476573;--rp-c-text-code-bg:#99a1b31a;--rp-c-brand:#0095ff;--rp-c-brand-light:#33adff;--rp-c-brand-lighter:#66c2ff;--rp-c-brand-dark:#07f;--rp-c-brand-darker:#005fcc;--rp-c-brand-tint:#7fa3ff29;--rp-c-gray:#8e8e8e;--rp-c-gray-light-1:#aeaeae;--rp-c-gray-light-2:#c7c7c7;--rp-c-gray-light-3:#d1d1d1;--rp-c-gray-light-4:#e5e5e5;--rp-c-gray-light-5:#f2f2f2;--rp-c-dark:#000;--rp-c-dark-light-1:#2f2f2f;--rp-c-dark-light-2:#3a3a3a;--rp-c-dark-light-3:#4a4a4a;--rp-c-dark-light-4:#5c5c5c;--rp-c-dark-light-5:#6b6b6b;--rp-radius:1rem;--rp-radius-small:.5rem;--rp-radius-large:1.5rem;--rp-c-link:var(--rp-c-brand-dark)}.dark{--rp-c-bg:#191d24;--rp-c-bg-soft:#292e37;--rp-c-bg-mute:#343a46;--rp-c-bg-alt:#000;--rp-c-divider:#545454a6;--rp-c-divider-light:#5454547a;--rp-c-text-1:#fffff5ed;--rp-c-text-2:#ebebeb8f;--rp-c-text-3:#ebebeb61;--rp-c-text-4:#ebebeb2e;--rp-c-text-code:#c9def1;--rp-c-link:var(--rp-c-brand-light)}:root{--rp-z-index-local-nav:10;--rp-z-index-nav:20;--rp-z-index-backdrop:30;--rp-z-index-sidebar:40;--rp-shadow-1:0 1px 4px #00000005,0 1px 0 #0000000f;--rp-shadow-2:0 3px 12px #00000012,0 1px 4px #00000012;--rp-shadow-3:0 12px 32px #0000001a,0 2px 6px #00000014;--rp-shadow-4:0 14px 44px #0000001f,0 3px 9px #0000001f;--rp-shadow-5:0 18px 56px #00000029,0 4px 12px #00000029}*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Noto Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{color:inherit;border-top-width:1px;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-feature-settings:normal;font-variation-settings:normal;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-feature-settings:inherit;font-variation-settings:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]{display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.bottom-0{bottom:0}.right-0{right:0}.top-8{top:2rem}.z-10{z-index:10}.z-\[1\]{z-index:1}.order-1{order:1}.order-2{order:2}.-m-1\.5{margin:-.375rem}.m-8{margin:2rem}.m-auto{margin:auto}.mx-0\.5{margin-left:.125rem;margin-right:.125rem}.mx-1\.5{margin-left:.375rem;margin-right:.375rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-3{margin-left:.75rem;margin-right:.75rem}.mx-auto{margin-left:auto;margin-right:auto}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-12{margin-top:3rem;margin-bottom:3rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.my-6{margin-top:1.5rem;margin-bottom:1.5rem}.mb-10{margin-bottom:2.5rem}.mb-11{margin-bottom:2.75rem}.mb-16{margin-bottom:4rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mr-2{margin-right:.5rem}.mr-auto{margin-right:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-10{margin-top:2.5rem}.mt-12{margin-top:3rem}.mt-2{margin-top:.5rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.mt-9{margin-top:2.25rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-12{height:3rem}.h-14{height:3.5rem}.h-4{height:1rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-\[50px\]{height:50px}.h-full{height:100%}.min-h-\[50vh\]{min-height:50vh}.w-12{width:3rem}.w-16{width:4rem}.w-32{width:8rem}.w-4{width:1rem}.w-6{width:1.5rem}.w-7{width:1.75rem}.w-\[50px\]{width:50px}.w-full{width:100%}.min-w-8{min-width:2rem}.max-w-6xl{max-width:72rem}.max-w-xl{max-width:36rem}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y))rotate(var(--tw-rotate))skewX(var(--tw-skew-x))skewY(var(--tw-skew-y))scaleX(var(--tw-scale-x))scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-center{align-content:center}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{column-gap:1rem}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-4xl{border-radius:2rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-t,.border-t-\[1px\]{border-top-width:1px}.border-solid{border-style:solid}.border-dashed{border-style:dashed}.border-brand{border-color:var(--rp-c-brand)}.border-current{border-color:currentColor}.border-divider{border-color:var(--rp-c-divider)}.border-divider-light{border-color:var(--rp-c-divider-light)}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.border-gray-light-3{border-color:var(--rp-c-gray-light-3)}.border-transparent{border-color:#0000}.bg-gray-light-1{background-color:var(--rp-c-gray-light-1)}.bg-white{background-color:var(--rp-c-bg)}.p-1{padding:.25rem}.p-16{padding:4rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-12{padding-bottom:3rem}.pb-2{padding-bottom:.5rem}.pb-5{padding-bottom:1.25rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-5{padding-left:1.25rem}.pl-6{padding-left:1.5rem}.pr-2{padding-right:.5rem}.pt-0{padding-top:0}.pt-2{padding-top:.5rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.pt-5{padding-top:1.25rem}.pt-6{padding-top:1.5rem}.pt-8{padding-top:2rem}.pt-9{padding-top:2.25rem}.text-center{text-align:center}.align-middle{vertical-align:middle}.text-2xl{font-size:1.625rem}.text-3xl{font-size:2rem}.text-6xl{font-size:3.75rem;line-height:1}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.25rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.375rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.leading-10{line-height:2.5rem}.leading-5{line-height:1.25rem}.leading-6{line-height:1.5rem}.leading-7{line-height:1.75rem}.leading-tight{line-height:1.25}.tracking-tight{letter-spacing:-.025em}.text-brand{color:var(--rp-c-brand)}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-text-1{color:var(--rp-c-text-1)}.text-text-2{color:var(--rp-c-text-2)}.opacity-80{opacity:.8}.outline{outline-style:solid}.blur{--tw-blur:blur(8px);filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.filter{filter:var(--tw-blur)var(--tw-brightness)var(--tw-contrast)var(--tw-grayscale)var(--tw-hue-rotate)var(--tw-invert)var(--tw-saturate)var(--tw-sepia)var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-all{transition-property:all;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-opacity{transition-property:opacity;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.transition-shadow{transition-property:box-shadow;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.\[counter-reset\:step\]{counter-reset:step}*,:before,:after{box-sizing:border-box}html{-webkit-text-size-adjust:100%;scroll-padding-top:var(--rp-nav-height);font-size:16px;line-height:1.7}html.dark{--lightningcss-light: ;--lightningcss-dark:initial;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}body{font-family:var(--rp-font-family-base);color:var(--rp-c-text-1);background-color:var(--rp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;direction:ltr;width:100%;min-width:320px;margin:0;font-size:16px;font-weight:400}button:focus{outline:none}button:focus-visible{outline:none}.visually-hidden{visibility:hidden}.flex-center{justify-content:center;align-items:center;display:flex}.menu{justify-content:space-around;align-items:center;font-size:.875rem;font-weight:700;line-height:1.25rem;display:flex}#nprogress .bar{background:var(--rp-c-brand);width:100%;height:2px;position:fixed;top:0;left:0}:root{--code-color-text:#414141;--code-color-background:transparent;--code-token-constant:#f59403;--code-token-string:#31a94d;--code-token-comment:#b6b4b4;--code-token-keyword:#cf2727;--code-token-parameter:#1976d2;--code-token-function:#7041c8;--code-token-string-expression:#218438;--code-token-punctuation:#242323;--code-token-link:#22863a;--code-token-variable:#1976d2;--code-token-symbol:#f59403;--code-token-deleted:#d32828;--code-token-inserted:#22863a}.dark{--code-color-text:#cac7c7;--code-token-constant:#6fb0fa;--code-token-string:#f9a86e;--code-token-comment:#6a727b;--code-token-keyword:#f47481;--code-token-parameter:#ff9800;--code-token-function:#ae8eeb;--code-token-string-expression:#4fb74d;--code-token-punctuation:#bbb;--code-token-link:#f9a76d;--code-token-variable:#6fb0fa;--code-token-symbol:#f9a86e;--code-token-deleted:#ee6d7a;--code-token-inserted:#36c47f}:root{--rp-font-family-base:"Inter var experimental","Inter var",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",sans-serif;--rp-font-family-mono:Menlo,Monaco,Consolas,"Courier New",monospace}.first\:mt-2:first-child{margin-top:.5rem}.last\:mr-0:last-child{margin-right:0}.even\:bg-soft:nth-child(2n){background-color:var(--rp-c-bg-soft)}.hover\:border-brand-dark:hover{border-color:var(--rp-c-brand-dark)}.hover\:border-gray-500:hover{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}.hover\:border-gray-600:hover{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}.hover\:bg-gray-100:hover{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.hover\:bg-mute:hover{background-color:var(--rp-c-bg-mute)}.hover\:text-brand-dark:hover{color:var(--rp-c-brand-dark)}.hover\:text-gray-600:hover{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity))}.hover\:text-text-1:hover{color:var(--rp-c-text-1)}.hover\:text-text-2:hover{color:var(--rp-c-text-2)}.hover\:opacity-60:hover{opacity:.6}.focus\:outline-none:focus{outline-offset:2px;outline:2px solid #0000}.focus\:ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-green-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(34 197 94/var(--tw-ring-opacity))}.focus\:ring-opacity-50:focus{--tw-ring-opacity:.5}.dark\:block:is(.dark *){display:block}.dark\:hidden:is(.dark *){display:none}.dark\:border-divider:is(.dark *){border-color:var(--rp-c-divider)}.dark\:border-gray-700:is(.dark *){--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}.dark\:border-gray-800:is(.dark *){--tw-border-opacity:1;border-color:rgb(31 41 55/var(--tw-border-opacity))}.dark\:hover\:border-gray-200:hover:is(.dark *){--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.dark\:hover\:text-gray-200:hover:is(.dark *){--tw-text-opacity:1;color:rgb(229 231 235/var(--tw-text-opacity))}@media (min-width:640px){.sm\:m-4{margin:1rem}.sm\:mt-0{margin-top:0}.sm\:flex{display:flex}.sm\:hidden{display:none}.sm\:max-w-4xl{max-width:56rem}.sm\:max-w-xl{max-width:36rem}.sm\:flex-1{flex:1}.sm\:flex-row{flex-direction:row}.sm\:items-center{align-items:center}.sm\:justify-around{justify-content:space-around}.sm\:p-8{padding:2rem}.sm\:px-16{padding-left:4rem;padding-right:4rem}.sm\:pb-2{padding-bottom:.5rem}.sm\:pb-40{padding-bottom:10rem}.sm\:pl-4{padding-left:1rem}.sm\:pr-2{padding-right:.5rem}.sm\:pt-10{padding-top:2.5rem}.sm\:pt-24{padding-top:6rem}.sm\:pt-8{padding-top:2rem}.sm\:text-5xl{font-size:3rem;line-height:1}.sm\:text-6xl{font-size:3.75rem;line-height:1}.sm\:leading-8{line-height:2rem}}@media (min-width:768px){.md\:order-1{order:1}.md\:order-2{order:2}.md\:m-0{margin:0}.md\:ml-1{margin-left:.25rem}.md\:mr-2{margin-right:.5rem}.md\:flex{display:flex}.md\:flex-row{flex-direction:row}.md\:flex-wrap{flex-wrap:wrap}.md\:justify-center{justify-content:center}.md\:px-16{padding-left:4rem;padding-right:4rem}.md\:pb-16{padding-bottom:4rem}.md\:pb-3{padding-bottom:.75rem}.md\:pt-16{padding-top:4rem}.md\:text-6xl{font-size:3.75rem;line-height:1}.md\:text-7xl{font-size:4.5rem;line-height:1}.md\:text-\[1\.5rem\]{font-size:1.5rem}}@media (min-width:1024px){.lg\:flex{display:flex}.lg\:hidden{display:none}.lg\:pb-2{padding-bottom:.5rem}}.\[\&\:not\(\:first-child\)\]\:mt-2:not(:first-child){margin-top:.5rem}:root{--rp-code-font-size:14px;--rp-code-block-color:#2e3440;--rp-code-title-bg:#0063c70d;--rp-code-block-bg:#f6f8fa;--rp-code-line-highlight-color:#0063c71a;--rp-code-line-number-color:#ebebeb61;--rp-code-copy-code-hover-bg:#ffffff0d;--rp-code-wrap-code-hover-bg:#ffffff0d}.dark{--rp-code-block-color:#e5e7eb;--rp-code-block-bg:#242424;--rp-code-title-bg:#ffffff0a;--rp-code-line-highlight-color:#ffffff1a;--rp-code-line-number-color:#3c3c3c54}.rspress-doc :not(:-webkit-any(pre,h1,h2,h3,h4,h5,h6))>code{font-size:var(--rp-code-font-size)}.rspress-doc :not(:-moz-any(pre,h1,h2,h3,h4,h5,h6))>code{font-size:var(--rp-code-font-size)}.rspress-doc :not(:-webkit-any(pre,h1,h2,h3,h4,h5,h6))>code{font-size:var(--rp-code-font-size)}.rspress-doc :not(:-moz-any(pre,h1,h2,h3,h4,h5,h6))>code{font-size:var(--rp-code-font-size)}.rspress-doc :not(:is(pre,h1,h2,h3,h4,h5,h6))>code{font-size:var(--rp-code-font-size)}.rspress-doc :not(:-webkit-any(pre,div))>code{border-radius:var(--rp-radius-small);color:var(--rp-c-text-code);background-color:var(--rp-c-text-code-bg);overflow-wrap:break-word;padding:3px 6px}.rspress-doc :not(:-moz-any(pre,div))>code{border-radius:var(--rp-radius-small);color:var(--rp-c-text-code);background-color:var(--rp-c-text-code-bg);overflow-wrap:break-word;padding:3px 6px}.rspress-doc :not(:-webkit-any(pre,div))>code{border-radius:var(--rp-radius-small);color:var(--rp-c-text-code);background-color:var(--rp-c-text-code-bg);overflow-wrap:break-word;padding:3px 6px}.rspress-doc :not(:-moz-any(pre,div))>code{border-radius:var(--rp-radius-small);color:var(--rp-c-text-code);background-color:var(--rp-c-text-code-bg);overflow-wrap:break-word;padding:3px 6px}.rspress-doc :not(:is(pre,div))>code{border-radius:var(--rp-radius-small);color:var(--rp-c-text-code);background-color:var(--rp-c-text-code-bg);overflow-wrap:break-word;padding:3px 6px}.rspress-doc h1>code,.rspress-doc h2>code,.rspress-doc h3>code{font-size:.9em}.rspress-doc a>code{color:var(--rp-c-brand-dark);transition:color .25s}.rspress-doc a:hover>code{color:var(--rp-c-brand)}.rspress-doc div[class^=language-]{background-color:var(--rp-code-block-bg);margin:16px 0;transition:none;position:relative;overflow-x:auto}.rspress-doc .rspress-code-title{font-size:var(--rp-code-font-size);background-color:var(--rp-code-title-bg);padding:12px 16px;transition:background-color .5s}@media (min-width:640px){.rspress-doc div[class^=language-]{border-radius:var(--rp-radius);contain:content;margin:24px 0}}@media (max-width:640px){.rspress-doc li div[class^=language-]{border-radius:var(--rp-radius-small)0 0 var(--rp-radius-small)}}.rspress-doc [class^=language-] pre,.rspress-doc [class^=language-] code{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}.rspress-doc [class^=language-] pre{z-index:1;background:0 0;margin:0;position:relative;overflow-x:auto}.rspress-doc [class^=language-] code{line-height:1.7;font-size:var(--rp-code-font-size);color:var(--rp-code-block-color);background-color:var(--rp-code-block-bg);width:-moz-fit-content;width:fit-content;min-width:100%;padding:16px 0;transition:color .5s;display:block}.rspress-doc [class^=language-] .rspress-code-content{position:relative}.rspress-doc [class^=language-] .rspress-code-content span.highlighted{background-color:var(--rp-code-line-highlight-color);padding-left:20px;display:block;position:absolute;left:0;right:0}.rspress-doc [class^=language-] .rspress-code-content>code{padding:16px 20px}.rspress-scrollbar{scrollbar-gutter:stable}.rspress-scrollbar::-webkit-scrollbar{width:12px;height:8px;transition:all .3s}.rspress-scrollbar::-webkit-scrollbar-track{background:0 0}.rspress-scrollbar::-webkit-scrollbar-thumb{border-radius:var(--rp-radius-small)}.rspress-scrollbar:hover::-webkit-scrollbar-thumb{background-color:var(--rp-c-text-4);background-clip:content-box;border:3px solid #0000}.rspress-scrollbar::-webkit-scrollbar-corner{background:0 0}.aside-link{border-radius:var(--rp-radius-small)0 0 var(--rp-radius-small);margin-bottom:1px;padding:.25rem 0}.aside-link:hover{background-color:var(--rp-c-bg-mute)}.aside-link.aside-active,.aside-link.aside-active:hover{color:var(--rp-c-link);background-color:var(--rp-c-brand-tint)}.aside-link-text{padding:0 12px;font-size:.8125rem;line-height:1.25rem}@media (min-width:640px){.pager_e7091{flex-direction:column;width:50%;display:flex}.pager_e7091.has-next_e7091{padding-top:0;padding-left:16px}}.prev_e7091,.next_e7091{width:100%}.rspress-sidebar-menu{z-index:var(--rp-z-index-local-nav);border-bottom:1px solid var(--rp-c-divider-light);border-top:1px solid var(--rp-c-divider-light);color:var(--rp-c-text-1);background-color:var(--rp-c-bg);justify-content:space-between;align-items:center;width:100%;padding-left:10px;display:flex;position:sticky;top:0;left:0}.rspress-sidebar-menu>button{background-color:#0000;padding:12px;transition:color .5s}.rspress-sidebar-menu>button:hover{color:var(--rp-c-text-3)}.rspress-sidebar-menu:empty{display:none}.rspress-sidebar-back-drop{z-index:var(--rp-z-index-backdrop);position:fixed;top:0;bottom:0;left:0;right:0}@media (min-width:960px){.rspress-sidebar-menu{display:none}}.rspress-local-toc-container{border-radius:var(--rp-radius-small);top:calc(var(--rp-nav-height) - 14px);background-color:var(--rp-c-bg-soft);max-height:calc(100vh - var(--rp-nav-height) - 20px);box-shadow:var(--rp-shadow-1);border:1px solid var(--rp-c-divider-light);padding:6px;position:absolute;left:20px;right:20px;overflow:scroll}.fly-in-enter{opacity:0;transform:translateY(-16px)}.fly-in-enter-active{opacity:1;transition:opacity .3s,transform .3s;transform:translate(0)}.fly-in-exit,.fly-in-exit-active{opacity:0;transition:none}.aside-container_edeb4{margin-top:calc(var(--rp-nav-height)*-1 - 32px);padding-top:calc(var(--rp-nav-height) + 32px);scrollbar-width:none;max-height:calc(100vh - var(--rp-nav-height) + 32px);width:0;display:none;position:sticky;top:0;overflow:hidden auto}.aside-container_edeb4::-webkit-scrollbar{display:none}.rspress-doc{view-transition-name:flip;min-height:60vh}@keyframes fade-out_edeb4{0%{opacity:1}to{opacity:0;transform:translateY(20px)}}@keyframes fade-in_edeb4{0%{opacity:0;transform:translateY(20px)}to{opacity:1}}::view-transition-old(flip){animation-time:.25s}::view-transition-new(flip){animation-time:.25s}::view-transition-old(flip){transition-timing-function:ease-out;animation-name:fade-out_edeb4}::view-transition-new(flip){transition-timing-function:ease-in;animation-name:fade-in_edeb4;animation-delay:.18s}@media (max-width:960px){.docLayout_edeb4{position:relative}.content_edeb4{padding:36px 24px 72px}.rspress-doc{view-transition-name:none}}@media (min-width:960px){.docLayout_edeb4{width:100%;display:flex}.content_edeb4{width:calc(100% - var(--rp-sidebar-width));padding:48px 48px 72px max(24px,48px - var(--rp-sidebar-width))}.content_edeb4 .rspress-doc,.content_edeb4 .rspress-doc-footer{width:100%}.aside-container_edeb4{width:var(--rp-aside-width)}}@media (min-width:1280px){.aside-container_edeb4{width:var(--rp-aside-width);display:block}.content_edeb4{padding:48px 0 72px}.content_edeb4 .rspress-doc,.content_edeb4 .rspress-doc-footer{box-sizing:border-box;width:calc(100vw - var(--rp-sidebar-width) - var(--rp-aside-width));max-width:min(100%,1056px);margin:auto;padding:0 48px}}@media (min-width:1440px){.docLayout_edeb4{width:100%;margin-left:0}.content_edeb4 .rspress-doc,.content_edeb4 .rspress-doc-footer{box-sizing:border-box;width:calc(100vw - var(--rp-sidebar-width) - var(--rp-aside-width));max-width:min(100%,1056px);margin:auto;padding:0 48px}}:root{--rp-home-hero-name-color:transparent;--rp-home-hero-name-background:-webkit-linear-gradient(120deg,var(--rp-c-brand)30%,#42d392);--rp-home-hero-image-background-image:none;--rp-home-hero-image-filter:none;--rp-home-feature-bg:var(--rp-c-bg-soft);--rp-home-mask-background-image:conic-gradient(from 180deg at 50% 50%,var(--rp-c-brand)0deg,180deg,#42d392 1turn);--rp-home-hero-image-width-sm:250px;--rp-home-hero-image-width:375px;--rp-home-hero-text-max-width:40rem}.dark{--rp-home-bg:#000;--rp-home-feature-bg:var(--rp-c-bg-soft)}.title_3b154{outline:none;font-weight:600;position:relative}.title_3b154 .header-anchor{float:left;opacity:0;font-weight:500;font-size:inherit;margin-left:-.8em;transition:color .25s,opacity .25s}.title_3b154:hover .header-anchor,.title_3b154 .header-anchor:focus{opacity:1}.blockquote_3b154 p,summary .blockquote_3b154 p{color:var(--rp-c-text-2);margin:0;font-size:16px}.link_3b154:not(.header-anchor),summary .link_3b154:not(.header-anchor),summary a:not(.header-anchor){color:var(--rp-c-link);font-weight:500;transition:color .25s}.link_3b154:hover,summary .link_3b154:hover,summary a:hover{border-bottom:1px solid var(--rp-c-brand)}.header-anchor{color:var(--rp-c-brand)}.rspress-doc details{font-size:normal;cursor:pointer;margin:16px 0;padding:8px;transition:all .3s}.rspress-doc details p{margin:8px 0}.rspress-doc details:hover{background-color:var(--rp-c-bg-mute)}.inline-link_3b154{overflow-wrap:break-word;display:inline}span.code-line-highlighted{background-color:var(--rp-code-line-highlight-color)}.rspress-code-content:hover .code-button-group_15153>button{opacity:1}.code-button-group_15153{z-index:10;gap:10px;display:flex;position:absolute;top:20px;right:20px}.code-button-group_15153>button{opacity:0;background-color:#0000;justify-content:center;align-items:center;display:flex;position:relative}.code-button-group_15153 svg{opacity:inherit;color:var(--rp-c-text-3);width:20px;height:20px;transition:all .2s}.code-button-group_15153 svg:hover{color:var(--rp-c-text-2)}.code-copy-button_15153 .icon-success_15153{opacity:0;color:#00d600;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)scale(0)}.code-copied_15153 .icon-copy_15153{opacity:0;transform:scale(.33)}.code-copied_15153 .icon-success_15153{opacity:1;transition-delay:75ms;transform:translate(-50%,-50%)scale(1)}.icon-wrapped_15153{opacity:0;color:#00d600;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)scale(0)}.wrapped-btn_15153 .icon-wrap_15153{opacity:0;transform:scale(.33)}.wrapped-btn_15153 .icon-wrapped_15153{opacity:1;transition-delay:75ms;transform:translate(-50%,-50%)scale(1)}.badge_99dcf{font-weight:500;transition:color .25s}.badge_99dcf.tip_99dcf{color:var(--rp-container-tip-text);background-color:var(--rp-container-tip-bg)}.badge_99dcf.info_99dcf{color:var(--rp-container-info-text);background-color:var(--rp-container-info-bg)}.badge_99dcf.warning_99dcf{color:var(--rp-container-warning-text);background-color:var(--rp-container-warning-bg)}.badge_99dcf.danger_99dcf{color:var(--rp-container-danger-text);background-color:var(--rp-container-danger-bg)}.badge_99dcf.outline_99dcf{border:1px solid}.badge_99dcf.outline_99dcf.tip_99dcf{border-color:var(--rp-container-tip-border)}.badge_99dcf.outline_99dcf.info_99dcf{border-color:var(--rp-container-info-border)}.badge_99dcf.outline_99dcf.warning_99dcf{border-color:var(--rp-container-warning-border)}.badge_99dcf.outline_99dcf.danger_99dcf{border-color:var(--rp-container-danger-border)}.button_72e53{text-align:center;white-space:nowrap;height:48px;font-weight:700;line-height:48px;display:inline-block}.button_72e53:active{transition:color .1s,border-color .1s,background-color .1s}.button_72e53.medium_72e53{border-radius:var(--rp-radius);height:38px;padding:0 20px;font-size:14px;line-height:38px}.button_72e53.big_72e53{border-radius:var(--rp-radius-large);min-width:142px;font-size:16px;font-weight:700}.button_72e53.brand_72e53,.button_72e53.brand_72e53:hover,.button_72e53.brand_72e53:active{opacity:1;color:#fff;transition:all .3s}.button_72e53.brand_72e53{background:linear-gradient(275deg,var(--rp-c-brand-dark)3%,var(--rp-c-brand-light)97%)}.button_72e53.brand_72e53:hover{background-color:var(--rp-c-brand-light);opacity:.8}.button_72e53.alt_72e53,.button_72e53.alt_72e53:hover,.button_72e53.alt_72e53:active{border:1px solid var(--rp-c-gray-light-3);color:var(--rp-c-text-1);background-color:var(--rp-c-gray-light-5);transition:all .3s}.dark .button_72e53.alt_72e53{background-color:var(--rp-c-bg-mute);color:var(--rp-c-text-1);border-color:#484848}.button_72e53.alt_72e53:hover{background-color:var(--rp-c-gray-light-4)}.dark .button_72e53.alt_72e53:hover{background-color:#484848}@media (max-width:768px){.button_72e53.big_72e53{min-width:100px;height:42px;font-size:14px;line-height:42px}}.editLink_2a169{color:var(--rp-c-brand);margin:20px 0;font-size:15px;font-weight:500;text-decoration:none;transition:all .2s ease-in-out}.editLink_2a169:hover{color:var(--rp-c-brand-dark)}@media (max-width:640px){.grid-2_d48e3,.grid-4_d48e3,.grid-6_d48e3{width:100%}}@media (min-width:640px){.grid-2_d48e3,.grid-4_d48e3,.grid-6_d48e3{width:50%}}@media (min-width:768px){.grid-2_d48e3,.grid-4_d48e3{width:50%}.grid-3_d48e3,.grid-6_d48e3{width:33.3333%}}@media (min-width:960px){.grid-3_d48e3{width:25%}.grid-4_d48e3{width:33.3333%}.grid-6_d48e3{width:50%}}.featureCard_d48e3{background:var(--rp-home-feature-bg);border:1px solid #0000;transition:all .3s}.featureCard_d48e3:hover{border:1px solid var(--rp-c-brand)}.clip_c867a{background:var(--rp-home-hero-name-background);-webkit-text-fill-color:var(--rp-home-hero-name-color);-webkit-background-clip:text;background-clip:text}.mask_c867a{background-image:var(--rp-home-mask-background-image);mixblendmode:normal;filter:blur(80px);opacity:.05;z-index:0;border-radius:100%;width:100%;max-width:500px;height:500px;margin-top:-250px;position:absolute;top:50%;transform:translate(-50%)}.dark .mask_c867a{opacity:.15}@media (min-width:640px){.rspress-home-hero-image{width:var(--rp-home-hero-image-width)}}@media (max-width:640px){.rspress-home-hero-image{max-width:var(--rp-home-hero-image-width-sm)}}@media (max-width:768px){.mask_c867a{display:none}}.link_03735{font-weight:500;transition:opacity .2s}.link_03735:hover{opacity:.85}.link_03735:active{opacity:.7}.link_9ef55:before{content:"";position:absolute;top:0;bottom:0;left:0;right:0}.rspress-nav-menu-group-button{background-color:#0000}.hidden_f6cde{opacity:0;background:0 0;transform:translateY(-100%)}.container_f6cde{margin:auto}.navContainer_f6cde{background:var(--rp-c-bg);height:var(--rp-nav-height);z-index:var(--rp-z-index-nav);transition:transform .3s,opacity .3s;top:0;left:0}.leftNav_f6cde,.rightNav_f6cde{display:none}.singleItem_f6cde{word-break:keep-all}.activeItem_f6cde,.singleItem_f6cde:hover{background-color:var(--rp-c-bg-mute);cursor:pointer;color:var(--rp-c-link);border-radius:var(--rp-radius)}.navBarTitle_f6cde{flex-shrink:0}.navContainer_f6cde *{pointer-events:all}.social-links-icon_f6cde{fill:currentColor;color:var(--rp-c-text-2);width:20px;height:100%;display:flex}.social-links-icon_f6cde:hover{color:var(--rp-c-text-1)}.menu-item_f6cde{margin:0 8px;display:none}@media (max-width:768px){:root{--rp-nav-height:56px}.menu-item_f6cde:before{display:none}.mobileNavMenu_f6cde{display:flex}}@media (min-width:768px){.menu-item_f6cde{display:flex}.leftNav_f6cde{flex-grow:1;align-items:center;margin:0 .5rem;display:flex}.rightNav_f6cde{align-items:center;display:flex}.mobileNavMenu_f6cde{display:none}}@media (min-width:960px){.mask_f6cde{width:100vw;height:30px;position:absolute;bottom:-30px;right:0}.mask_f6cde.docPage_f6cde{width:calc(100vw - var(--rp-sidebar-width) - 48px)}.mask_f6cde:before{background:linear-gradient(var(--rp-c-bg),transparent 60%);content:"";width:100%;height:30px;display:block}.leftNav_f6cde{margin:0 2rem}}::view-transition-old(root){mix-blend-mode:normal;animation:none}::view-transition-new(root){mix-blend-mode:normal;animation:none}::view-transition-old(root){z-index:1}.dark::view-transition-new(root){z-index:1}::view-transition-new(root){z-index:9999}.dark::view-transition-old(root){z-index:9999}.social-links-icon_93d67{fill:currentColor;color:var(--rp-c-text-2);align-items:center;width:24px;height:24px;margin-left:.5rem;display:flex}.social-links-icon_93d67:hover{color:var(--rp-c-text-1)}@media (max-width:768px){.menu-item_93d67:before{display:none}a:only-child .social-links-icon_93d67{margin-left:0}}.navScreen_457e8{top:var(--rp-nav-height);background-color:var(--rp-c-bg);pointer-events:auto;z-index:20;width:100%;padding:32px;display:none;position:fixed;bottom:0;left:0;right:0;overflow-y:auto}.active_457e8{display:block}.container_457e8{max-width:248px;margin:0 auto;padding:24px 0 96px}.navMenu_457e8{flex-direction:column;justify-content:center;align-items:center;display:flex}.navMenuItem_457e8{color:var(--rp-c-text-1);border-bottom:1px solid var(--rp-c-divider-light);justify-content:center;padding:12px 0 11px;font-size:14px;font-weight:500;line-height:24px;transition:border-color .5s,color .25s;display:flex}.navAppearance_457e8{padding-right:0}.socialAndAppearance_457e8{padding:8px 0 7px}.navScreenMenuGroup_457e8{height:39px;transition:border-color .5s;overflow:hidden}.navScreenMenuGroup_457e8.open_457e8{height:auto;padding-bottom:10px}.button_457e8{color:var(--rp-c-text-1);background-color:#0000;justify-content:center;align-items:center;width:100%;padding:8px 0 7px;font-size:14px;font-weight:500;line-height:24px;transition:color .25s;display:flex}.buttonSpan_457e8{align-items:center;height:24px;padding-right:4px;display:flex}.navScreenMenuGroup_457e8 .items_457e8{visibility:hidden}.navScreenMenuGroup_457e8.open_457e8 .items_457e8{visibility:visible}.down_457e8{transition:all .5s}.open_457e8.down_457e8{transform:rotate(180deg)}.navHamburger_e7b06{background-color:#0000;justify-content:center;align-items:center;width:36px;height:56px;margin-left:6px;display:flex}@media (min-width:768px){.navHamburger_e7b06{display:none}}.container_e7b06{width:16px;height:14px;position:relative;overflow:hidden}.navHamburger_e7b06:hover .top_e7b06{top:0;left:0;transform:translate(4px)}.navHamburger_e7b06:hover .middle_e7b06{top:6px;left:0;transform:translate(0)}.navHamburger_e7b06:hover .bottom_e7b06{top:12px;left:0;transform:translate(8px)}.navHamburger_e7b06.active_e7b06 .top_e7b06{top:6px;transform:translate(0)rotate(225deg)}.navHamburger_e7b06.active_e7b06 .middle_e7b06{top:6px;transform:translate(16px)}.navHamburger_e7b06.active_e7b06 .bottom_e7b06{top:6px;transform:translate(0)rotate(135deg)}.navHamburger_e7b06.active_e7b06:hover .top_e7b06,.navHamburger_e7b06.active_e7b06:hover .middle_e7b06,.navHamburger_e7b06.active_e7b06:hover .bottom_e7b06{transition:top .25s,background-color .25s,transform .25s}.top_e7b06,.middle_e7b06,.bottom_e7b06{background-color:var(--rp-c-text-2);width:16px;height:1.5px;transition:top .25s,background-color .5s,transform .25s;position:absolute}.top_e7b06{top:0;left:0;transform:translate(0)}.middle_e7b06{top:6px;left:0;transform:translate(8px)}.bottom_e7b06{top:12px;left:0;transform:translate(4px)}.overview-index h1,.overview-index h2,.overview-index h3{font-weight:600}.overview-index h2,.overview-index h3{line-height:1}.overview-index h2{letter-spacing:-.02em;color:var(--rp-c-text-1);border-top:1px solid var(--rp-c-divider-light);margin:36px 0;padding-top:36px;font-size:24px;transition:color .5s}.overview-index h3,.overview-index h3>a{letter-spacing:-.01em;color:var(--rp-c-link);margin-bottom:1em;font-size:18px;font-weight:600;transition:color .5s}.overview-index h3>a{margin:0;line-height:1.3}.overview-index h3:before{display:none}.overview-index h1:hover .header-anchor_8f375,.overview-index h1:focus .header-anchor_8f375,.overview-index h2:hover .header-anchor_8f375,.overview-index h2:focus .header-anchor_8f375,.overview-index h3:hover .header-anchor_8f375,.overview-index h3:focus .header-anchor_8f375,.overview-index h4:hover .header-anchor_8f375,.overview-index h4:focus .header-anchor_8f375,.overview-index h5:hover .header-anchor_8f375,.overview-index h5:focus .header-anchor_8f375,.overview-index h6:hover .header-anchor_8f375,.overview-index h6:focus .header-anchor_8f375{opacity:1}.overview-index a.header-anchor_8f375{float:left;opacity:0;color:var(--rp-c-brand);margin-top:.125em;margin-left:-.87em;padding-right:.23em;font-size:.85em;font-weight:500;text-decoration-style:dotted;transition:color .25s}.overview-index a.header-anchor_8f375:hover,.overview-index a.header-anchor_8f375:focus{text-decoration:none}.overview-groups_8f375 a{color:var(--rp-c-text-code);overflow-wrap:break-word;margin-top:8px;font-size:15px;font-weight:500;line-height:1.6;transition:color .5s;display:block}.overview-group-li_8f375{position:relative}.overview-group-li_8f375.level-2_8f375{padding-left:1px}.overview-group-li_8f375.level-2_8f375:before{left:-.25rem}.overview-group-li_8f375.level-3_8f375{padding-left:8px}.overview-group-li_8f375.level-3_8f375:before{left:-.25rem}.overview-group-li_8f375.level-4_8f375{padding-left:16px}.overview-group-li_8f375.level-4_8f375:before{left:-.25rem}.overview-group_8f375{break-inside:avoid;background-color:var(--rp-c-bg-soft);border-radius:var(--rp-radius);margin-bottom:28px;padding:28px 32px;transition:background-color .5s}@media (max-width:768px){.overview-index{padding:42px 24px}.overview-index h1{margin-bottom:24px;font-size:32px}.overview-index h2{margin:42px 0 32px;padding-top:32px;font-size:22px}.overview-groups_8f375 a{font-size:14px}.header_8f375{display:block}}@media (min-width:768px){.overview-groups_8f375{columns:2}}@media (min-width:1024px){.overview-groups_8f375{columns:3}}.rspress-package-manager-tabs div[class*=language-] code{background-color:var(--rp-c-bg-mute)!important}.pager-link_9b9a7{border-radius:var(--rp-radius);width:100%;height:100%;padding:16px 20px;transition:border-color .25s;display:block;border:1px solid var(--rp-c-divider-light)!important}.pager-link_9b9a7:hover{border-color:var(--rp-c-brand)!important}.pager-link_9b9a7:hover .title_9b9a7{color:var(--rp-c-brand-dark)}.pager-link_9b9a7.next_9b9a7{text-align:right;margin-left:auto}.desc_9b9a7{color:var(--rp-c-text-2);font-size:12px;font-weight:500;line-height:20px;display:block}.title_9b9a7{color:var(--rp-c-brand);font-size:14px;font-weight:500;line-height:24px;transition:color .25s;display:block}.scroll-to-top_1a167{z-index:1;color:var(--rp-c-text-1);border-color:var(--rp-c-text-3);background-color:var(--rp-c-bg-soft);box-shadow:0 1px 3px 0 var(--rp-shadow-1),0 1px 2px 0 var(--rp-shadow-2);border-width:.1px;border-radius:9999px;padding:.5rem;transition-property:transform;transition-duration:75ms;transition-timing-function:cubic-bezier(.4,0,.2,1);position:fixed;bottom:1rem;right:1rem;transform:scale(0)}.scroll-to-top_1a167.entered_1a167{transform:scale(1)!important}.mask_6e282{z-index:100;background:#545454b3;position:fixed;top:0;bottom:0;left:0;right:0}.modal_6e282{background-color:var(--rp-c-bg-soft);border-radius:var(--rp-radius);max-width:560px;height:auto;margin:80px auto auto;padding:20px;position:relative}.inputForm_6e282{background-color:var(--rp-c-bg);border:1px solid var(--rp-c-brand);border-radius:var(--rp-radius-small);align-items:center;width:100%;height:55px;padding:0 12px;display:flex}.inputForm_6e282 .input_6e282{background-color:var(--rp-c-bg);outline:none;flex:1;width:80%;height:100%;padding-left:8px;font-size:20px;font-weight:500}.dark .inputForm_6e282 .input_6e282{color:var(--rp-c-text)}.close_6e282:hover{cursor:pointer;color:var(--rp-c-brand);transition:color .3s}.searchHits_6e282{max-height:calc(100vh - 230px);padding-right:2px;overflow:scroll}.searchHits_6e282 .groupTitle_6e282{background-color:var(--rp-c-bg-soft);color:var(--rp-c-brand-dark);margin:0;padding-top:6px;padding-bottom:6px;padding-left:2px;font-size:13px;font-weight:600;position:sticky;top:0;left:0}.navSearchButton_6e282{border-radius:var(--rp-radius);background-color:var(--rp-c-bg-mute);border:1px solid #0000;width:100%;height:40px;padding:0 10px;transition:border-color .3s;display:flex}.navSearchButton_6e282>button{cursor:pointer;background-color:#0000;justify-content:space-around;align-items:center;font-size:13px;display:flex}.navSearchButton_6e282>button .searchWord_6e282{white-space:nowrap;color:var(--rp-c-text-2);margin-left:5px;margin-right:40px;font-weight:500;transition:all .3s}.navSearchButton_6e282>button>div{border-radius:var(--rp-radius-small);color:var(--rp-c-gray);background-color:var(--rp-c-bg);width:43px;font-weight:500;transition:opacity .3s}.navSearchButton_6e282>button>div>span{margin-left:5px}.navSearchButton_6e282>button>div>span+span{margin-right:5px}.navSearchButton_6e282:hover{border:1px solid var(--rp-c-brand)}.navSearchButton_6e282:hover>button .searchWord_6e282{color:var(--rp-c-text-1)}.suggestItem_6e282{box-sizing:border-box;margin:5px 2px;list-style:none}.dark .suggestItem_6e282,.dark .suggestItem_6e282>a{box-shadow:none}.suggestItem_6e282>a{background-color:var(--rp-c-bg);border-radius:var(--rp-radius-small);color:var(--rp-c-black-soft);width:100%;padding-left:12px;display:flex;box-shadow:0 1px 3px #d4d9e1}.suggestItem_6e282>a .suggestItemContainer_6e282{align-items:center;width:100%;min-height:56px;padding-right:12px;font-weight:500;display:flex}.suggestItem_6e282>a .suggestItemContainer_6e282 .contentWrapper_6e282{width:100%;padding:6px 8px;font-size:14px;line-height:1.5}.suggestItem_6e282>a .suggestItemContainer_6e282 .contentWrapper_6e282 .mark_6e282{color:var(--rp-c-brand)}.suggestItem_6e282>a .suggestItemContainer_6e282 .contentWrapper_6e282 .titleForContent_6e282{color:var(--rp-c-gray-light-1);font-size:12px;font-weight:600}.suggestItem_6e282>a .suggestItemContainer_6e282 svg{color:var(--rp-c-gray-light-1)}.suggestItem_6e282>a .suggestItemContainer_6e282 .actionIcon_6e282{opacity:0}.suggestItem_6e282.current_6e282>a{background-color:var(--rp-c-brand);cursor:pointer;color:#fff}.suggestItem_6e282.current_6e282 .suggestItemContainer_6e282 svg{color:#fff}.suggestItem_6e282.current_6e282 .suggestItemContainer_6e282 .actionIcon_6e282{opacity:1}.suggestItem_6e282.current_6e282 .suggestItemContainer_6e282 .contentWrapper_6e282 .mark_6e282{color:#fff;text-decoration:underline}.suggestItem_6e282.current_6e282 .suggestItemContainer_6e282 .contentWrapper_6e282 .titleForContent_6e282{color:#fff}.tabClassName_6e282{background-color:var(--rp-c-bg-soft);padding-bottom:6px;position:sticky}.mobileNavSearchButton_6e282{cursor:pointer;justify-content:center;align-items:center;font-weight:500;display:none}@media (max-width:960px){.navSearchButton_6e282{display:none}.mobileNavSearchButton_6e282{display:flex}.modal_6e282{margin-top:0}.inputForm_6e282{height:40px}.inputForm_6e282 svg{width:16px;height:16px}.inputForm_6e282 .input_6e282{font-size:16px}}.container_fa768{background-color:var(--rp-code-block-bg);contain:content;border-radius:var(--rp-radius)}.container_fa768 div[class*=language-]{margin:6px 0}.container_fa768 div[class*=language-] code{background-color:var(--rp-c-bg)}.tab-list_fa768{min-width:100%;padding-top:4px;padding-left:8px;display:flex;overflow-x:scroll}.tab_fa768{color:var(--rp-c-text-2);box-sizing:border-box;-webkit-user-select:none;user-select:none;cursor:pointer;border-bottom:2px solid #0000;margin-bottom:-1px;margin-right:10px;padding:6px 12px;transition:all .2s ease-in-out}.tab_fa768:last-child{margin-right:0}.not-selected_fa768:hover{color:var(--rp-c-text-1);border-color:var(--rp-c-gray)}.selected_fa768{color:var(--rp-c-link);border-color:currentColor}.no-scrollbar_fa768::-webkit-scrollbar{display:none}.no-scrollbar_fa768{-ms-overflow-style:none;scrollbar-width:none}.navTitleMask_71eca{height:var(--rp-nav-height);align-items:center;padding-left:1.5rem;display:flex}.sidebar_71eca{z-index:var(--rp-z-index-sidebar);opacity:0;background:var(--rp-c-bg);width:calc(100vw - 64px);max-width:320px;transition:opacity .5s,transform .25s;position:fixed;top:0;bottom:0;left:0;transform:translate(-100%)}.sidebarContent_71eca{max-height:calc(100% - var(--rp-nav-height));overflow:hidden auto}.sidebar_71eca.open_71eca{opacity:1;visibility:visible;transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1);transform:translate(0)}@media (min-width:960px){.sidebar_71eca{z-index:5;opacity:1;visibility:visible;margin-top:calc(var(--rp-nav-height)*-1);width:var(--rp-sidebar-width);box-shadow:var(--rp-c-shadow-3);--webkit-mask-image:linear-gradient(270deg,#000 10px,transparent 0);height:100vh;position:sticky;transform:translate(0);-webkit-mask-image:linear-gradient(#0000,#000 20px),linear-gradient(270deg,#000 10px,#0000 0);mask-image:linear-gradient(#0000,#000 20px),linear-gradient(270deg,#000 10px,#0000 0)}}@media (min-width:1440px){.sidebar_71eca{width:var(--rp-sidebar-width)}}.menuLink_71eca{opacity:1}.menuLink_71eca:hover{color:inherit;transition:all .2s}.menuItem_71eca:hover{color:var(--rp-c-text-1);background-color:var(--rp-c-bg-mute);transition:all .2s}.collapseContainer_71eca:hover{background-color:#e5e5e566;transition:all .2s}.dark .menuItem_71eca:hover,.dark .collapseContainer_71eca:hover{background-color:var(--rp-c-bg-mute);transition:all .2s}.menuItem_71eca,.menuItemActive_71eca{border-radius:0 var(--rp-radius)var(--rp-radius)0;font-size:13px;line-height:19px}.menuItem_71eca{color:var(--rp-c-text-2);font-weight:500;transition:color .2s}.menuItemActive_71eca{background-color:var(--rp-c-brand-tint);color:var(--rp-c-link);font-weight:bolder;position:relative}.menuItemActive_71eca:before{content:"";background-color:var(--rp-c-brand);width:1px;height:100%;transition:all .2s;position:absolute;top:0;left:0}.menuGroupActive_71eca{background-color:var(--rp-c-bg-mute)}.rspress-sidebar-group{position:relative}.rspress-sidebar-group:before{content:"";background-color:var(--rp-c-gray-light-4);width:1px;height:100%;position:absolute;top:0;left:18px}.rspress-sidebar-section-header{align-items:center;padding:8px 0 8px 16px;display:flex}.rspress-sidebar-section-header>span{color:var(--rp-c-text-1);align-items:center;margin-left:8px;font-size:14px;font-weight:700;line-height:20px;display:flex}.dark .rspress-sidebar-group:before{background-color:var(--rp-c-bg-mute)}.dark .sidebar_71eca{box-shadow:var(--rp-shadow-1)}.sourceCode_bf1b0{fill:currentColor;color:var(--rp-c-text-2)}.sourceCode_bf1b0:hover{color:var(--rp-c-text-1)}.rspressSteps_38f64 h3{counter-increment:step;margin-top:3px}.rspressSteps_38f64 h3:before{content:counter(step);text-align:center;color:var(--rp-c-text-1);background-color:var(--rp-code-block-bg);border-width:1.5px;border-color:var(--rp-c-text-3);border-radius:9999px;width:30px;height:30px;margin-left:-41px;font-size:1.1rem;font-weight:400;position:absolute}.rspressSteps_38f64{border-color:var(--rp-c-text-3)}.rspressSteps_38f64 p{color:var(--rp-c-text-1)}.rspress-toc-link{border-radius:var(--rp-radius-small);transition:all .3s;display:block}.rspress-toc-link-text{white-space:nowrap;text-overflow:ellipsis;border-radius:var(--rp-radius-small);color:var(--rp-c-text-2);padding:6px 12px;transition:all .2s ease-in-out;overflow:hidden}.rspress-toc-link-text:hover{background-color:var(--rp-c-bg-mute);color:var(--rp-c-text-1)}#nprogress{pointer-events:none}#nprogress .bar{z-index:1031;background:#29d;width:100%;height:2px;position:fixed;top:0;left:0}#nprogress .peg{opacity:1;width:100px;height:100%;display:block;position:absolute;right:0;transform:rotate(3deg)translateY(-4px);box-shadow:0 0 10px #29d,0 0 5px #29d}#nprogress .spinner{z-index:1031;display:block;position:fixed;top:15px;right:15px}#nprogress .spinner-icon{box-sizing:border-box;border:2px solid #0000;border-color:#29d #0000 #0000 #29d;border-radius:50%;width:18px;height:18px;animation:.4s linear infinite nprogress-spinner}.nprogress-custom-parent{position:relative;overflow:hidden}.nprogress-custom-parent #nprogress .spinner,.nprogress-custom-parent #nprogress .bar{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0)}to{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0)}to{transform:rotate(360deg)}}:root{--rp-c-brand:#00be50}.rspress-logo{height:60px}:root{--rp-container-note-border:var(--rp-c-divider-light);--rp-container-note-text:var(--rp-c-text-1);--rp-container-note-bg:var(--rp-c-bg-soft);--rp-container-note-code-bg:#8080801a;--rp-container-note-link:var(--rp-c-link);--rp-container-tip-border:#079c7033;--rp-container-tip-text:#278359;--rp-container-tip-bg:#079c700f;--rp-container-tip-code-bg:#079c701a;--rp-container-info-border:#0095ff33;--rp-container-info-text:#07f;--rp-container-info-bg:#0095ff0f;--rp-container-info-code-bg:#0095ff1a;--rp-container-warning-border:#ffc51766;--rp-container-warning-text:#887233;--rp-container-warning-bg:#ffc5171a;--rp-container-warning-code-bg:#ffc5171a;--rp-container-danger-border:#ed3c5033;--rp-container-danger-text:#ab2131;--rp-container-danger-bg:#ed3c5014;--rp-container-danger-code-bg:#ed3c501a;--rp-container-details-border:var(--rp-c-divider-light);--rp-container-details-text:var(--rp-c-text-1);--rp-container-details-bg:var(--rp-c-bg-soft);--rp-container-details-code-bg:#8080801a;--rp-container-details-link:var(--rp-c-link)}.dark{--rp-container-tip-text:#3ec480;--rp-container-tip-bg:#079c701a;--rp-container-info-text:#66c2ff;--rp-container-info-bg:#0095ff1a;--rp-container-warning-text:#fbb451;--rp-container-warning-border:#ffc51740;--rp-container-warning-bg:#ffc5171f;--rp-container-danger-text:#f76e85;--rp-container-danger-border:#ed3c504d;--rp-container-danger-bg:#ed3c501f}.rspress-doc .rspress-directive{border-radius:var(--rp-radius);border:1px solid #0000;margin:24px 0;padding:20px 24px 12px;font-size:14px;font-weight:400;line-height:1.7}.rspress-doc .rspress-directive .rspress-directive-title{margin-bottom:8px;font-size:16px;font-weight:600}.rspress-doc .rspress-directive .rspress-directive-content p{margin:8px 0}.rspress-doc .rspress-directive .rspress-directive-icon{width:20px;height:20px;margin-right:3px;display:inline-block}.rspress-doc .rspress-directive p{margin:8px 0}.rspress-doc .rspress-directive code{color:inherit;font-size:13px}.rspress-doc .rspress-directive a{border-bottom:1px solid;font-weight:500;transition:color .25s}.rspress-doc .rspress-directive.note{border-color:var(--rp-container-note-border);background-color:var(--rp-container-note-bg)}.rspress-doc .rspress-directive.note .rspress-directive-title{color:var(--rp-container-note-text)}.rspress-doc .rspress-directive.note code{color:var(--rp-container-note-text);background-color:var(--rp-container-note-code-bg)}.rspress-doc .rspress-directive.note a{color:var(--rp-container-note-text)}.rspress-doc .rspress-directive.tip{border-color:var(--rp-container-tip-border);background-color:var(--rp-container-tip-bg)}.rspress-doc .rspress-directive.tip .rspress-directive-title{color:var(--rp-container-tip-text)}.rspress-doc .rspress-directive.tip code{color:var(--rp-container-tip-text);background-color:var(--rp-container-tip-code-bg)}.rspress-doc .rspress-directive.tip a{color:var(--rp-container-tip-text)}.rspress-doc .rspress-directive.info{border-color:var(--rp-container-info-border);background-color:var(--rp-container-info-bg)}.rspress-doc .rspress-directive.info .rspress-directive-title{color:var(--rp-container-info-text)}.rspress-doc .rspress-directive.info code{color:var(--rp-container-info-text);background-color:var(--rp-container-info-code-bg)}.rspress-doc .rspress-directive.info a{color:var(--rp-container-info-text)}.rspress-doc .rspress-directive.warning{border-color:var(--rp-container-warning-border);background-color:var(--rp-container-warning-bg)}.rspress-doc .rspress-directive.warning .rspress-directive-title{color:var(--rp-container-warning-text)}.rspress-doc .rspress-directive.warning code{color:var(--rp-container-warning-text);background-color:var(--rp-container-warning-code-bg)}.rspress-doc .rspress-directive.warning a{color:var(--rp-container-warning-text)}.rspress-doc .rspress-directive.caution,.rspress-doc .rspress-directive.danger{border-color:var(--rp-container-danger-border);background-color:var(--rp-container-danger-bg)}.rspress-doc .rspress-directive.caution .rspress-directive-title,.rspress-doc .rspress-directive.danger .rspress-directive-title{color:var(--rp-container-danger-text)}.rspress-doc .rspress-directive.caution code,.rspress-doc .rspress-directive.danger code{color:var(--rp-container-danger-text);background-color:var(--rp-container-danger-code-bg)}.rspress-doc .rspress-directive.caution a,.rspress-doc .rspress-directive.danger a{color:var(--rp-container-danger-text)}.rspress-doc .rspress-directive.details{border-color:var(--rp-container-details-border);background-color:var(--rp-container-details-bg)}.rspress-doc .rspress-directive.details .rspress-directive-title{color:var(--rp-container-details-text)}.rspress-doc .rspress-directive.details code{color:var(--rp-container-details-text);background-color:var(--rp-container-details-code-bg)}.rspress-doc .rspress-directive.details a{color:var(--rp-container-details-link)} \ No newline at end of file diff --git a/static/js/async/191.0033d0fb.js b/static/js/async/191.0033d0fb.js new file mode 100644 index 00000000..f6de6d43 --- /dev/null +++ b/static/js/async/191.0033d0fb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkssr_docs=self.webpackChunkssr_docs||[]).push([["191"],{2729:function(e,s,r){r.r(s),r.d(s,{default:function(){return c}});var i=r(1549),n=r(6603);function d(e){let s=Object.assign({h1:"h1",a:"a",p:"p",pre:"pre",code:"code",h2:"h2",div:"div",ul:"ul",li:"li",strong:"strong"},(0,n.ah)(),e.components);return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(s.h1,{id:"命令",children:["命令",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#命令",children:"#"})]}),"\n",(0,i.jsx)(s.p,{children:"一个典型的命令配置。"}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-json",children:'{\n "scripts": {\n "dev": "gez dev",\n "build": "npm run build:ssr && npm run build:dts && npm run release",\n "build:ssr": "gez build",\n "build:dts": "vue-tsc --declaration --emitDeclarationOnly --noEmit false --outDir dist/server/src",\n "release": "gez release",\n "preview": "gez preview",\n "start": "gez start",\n "postinstall": "gez install"\n }\n}\n'})}),"\n",(0,i.jsxs)(s.h2,{id:"gez-dev",children:["gez dev",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#gez-dev",children:"#"})]}),"\n",(0,i.jsx)(s.p,{children:"本地开发时启动。"}),"\n",(0,i.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,i.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(s.div,{className:"rspress-directive-content",children:(0,i.jsx)(s.p,{children:"如果链接的服务是一个本地的目录,你也可以把该服务跑起来快速的开发调试。"})})]}),"\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-ts",children:"export default {\n name: 'ssr-module-auth',\n modules: {\n imports: {\n 'ssr-core': 'root:../ssr-core/dist'\n }\n }\n} satisfies GezOptions;\n"})}),"\n",(0,i.jsxs)(s.h2,{id:"gez-build",children:["gez build",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#gez-build",children:"#"})]}),"\n",(0,i.jsx)(s.p,{children:"构建生产代码"}),"\n",(0,i.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,i.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(s.div,{className:"rspress-directive-content",children:(0,i.jsx)(s.p,{children:"有三个产物,分别是 client、server、node。"})})]}),"\n",(0,i.jsxs)(s.h2,{id:"gez-release",children:["gez release",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#gez-release",children:"#"})]}),"\n",(0,i.jsx)(s.p,{children:"当前服务如果有对外导出模块时使用。"}),"\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:["执行 ",(0,i.jsx)(s.code,{children:"gez build"})," 命令,构建生产产物。"]}),"\n",(0,i.jsxs)(s.li,{children:["执行 ",(0,i.jsx)(s.code,{children:"npm run build:dts"})," 命令,将类型输出到 ",(0,i.jsx)(s.code,{children:"dist/server/src"})," 目录,本地开发时,可以得到类型提示。"]}),"\n",(0,i.jsxs)(s.li,{children:["执行 ",(0,i.jsx)(s.code,{children:"gez release"})," 命令,将 ",(0,i.jsx)(s.code,{children:"dist/client"})," 和 ",(0,i.jsx)(s.code,{children:"dist/server"})," 目录生成 zip 压缩文件,放到 ",(0,i.jsx)(s.code,{children:"dist/client/versions"})," 目录中。"]}),"\n",(0,i.jsxs)(s.li,{children:["将 ",(0,i.jsx)(s.code,{children:"dist"})," 目录的代码,部署到生产环境中。"]}),"\n",(0,i.jsxs)(s.li,{children:["其它服务调用","\n",(0,i.jsxs)(s.ul,{children:["\n",(0,i.jsxs)(s.li,{children:[(0,i.jsx)(s.strong,{children:"entry.node.ts"})," 配置","\n",(0,i.jsx)(s.pre,{children:(0,i.jsx)(s.code,{className:"language-ts",children:"export default {\n name: 'ssr-module-auth',\n modules: {\n imports: {\n 'ssr-core': ['root:../ssr-core/dist', 'https:///ssr-core/versions/latest.json']\n }\n }\n} satisfies GezOptions;\n"})}),"\n"]}),"\n",(0,i.jsxs)(s.li,{children:["执行 ",(0,i.jsx)(s.code,{children:"npm install"})," 命令,触发 ",(0,i.jsx)(s.code,{children:"postinstall"})," 钩子,再执行 ",(0,i.jsx)(s.code,{children:"gez install"})," 命令下载"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,i.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(s.div,{className:"rspress-directive-content",children:(0,i.jsxs)(s.p,{children:["可以封装一个 ",(0,i.jsx)(s.code,{children:"build"})," 命令,将多个命令封装到一起。\n"]})})]}),"\n",(0,i.jsxs)(s.h2,{id:"gez-preview",children:["gez preview",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#gez-preview",children:"#"})]}),"\n",(0,i.jsxs)(s.p,{children:["等同于执行 ",(0,i.jsx)(s.code,{children:"gez build && gez start"})]}),"\n",(0,i.jsxs)(s.h2,{id:"gez-start",children:["gez start",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#gez-start",children:"#"})]}),"\n",(0,i.jsx)(s.p,{children:"运行生产环境代码"}),"\n",(0,i.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,i.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsxs)(s.div,{className:"rspress-directive-content",children:[(0,i.jsx)(s.p,{children:"开发环境中,所依赖的外部服务代码变更,总是会获得热更新,但是在生产环境中是没有热更新的。"}),(0,i.jsx)(s.p,{children:"如果依赖的服务发布更新了,你需要手动重启一下服务,或者编写一个脚本,监听版本发布来重启服务。"})]})]}),"\n",(0,i.jsxs)(s.h2,{id:"gez-install",children:["gez install",(0,i.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#gez-install",children:"#"})]}),"\n",(0,i.jsx)(s.p,{children:"安装远程依赖到本地"}),"\n",(0,i.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,i.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,i.jsx)(s.div,{className:"rspress-directive-content",children:(0,i.jsxs)(s.p,{children:["在 ",(0,i.jsx)(s.code,{children:"postinstall"})," 钩子中,执行 ",(0,i.jsx)(s.code,{children:"npm install --production"})," 安装生产依赖无效。\n"]})})]})]})}function l(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:s}=Object.assign({},(0,n.ah)(),e.components);return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}let c=l;l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["guide%2Fessentials%2Fcommand.mdx"]={toc:[{text:"gez dev",id:"gez-dev",depth:2},{text:"gez build",id:"gez-build",depth:2},{text:"gez release",id:"gez-release",depth:2},{text:"gez preview",id:"gez-preview",depth:2},{text:"gez start",id:"gez-start",depth:2},{text:"gez install",id:"gez-install",depth:2}],title:"命令",frontmatter:{}}}}]); \ No newline at end of file diff --git a/static/js/async/418.60ed0315.js b/static/js/async/418.60ed0315.js new file mode 100644 index 00000000..a855c9e9 --- /dev/null +++ b/static/js/async/418.60ed0315.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkssr_docs=self.webpackChunkssr_docs||[]).push([["418"],{8707:function(e,n,r){r.r(n),r.d(n,{default:function(){return i}});var s=r(1549),t=r(6603),c=r(5789);function a(e){let n=Object.assign({h1:"h1",a:"a",p:"p",h2:"h2",pre:"pre",code:"code",strong:"strong",div:"div",h3:"h3",blockquote:"blockquote"},(0,t.ah)(),e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.h1,{id:"快速开始",children:["快速开始",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#快速开始",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"这是一个与框架无关的例子,采用原生的 HTML 来开发项目"}),"\n",(0,s.jsxs)(n.h2,{id:"创建项目",children:["创建项目",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#创建项目",children:"#"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd 项目目录\nnpm init\n"})}),"\n",(0,s.jsxs)(n.h2,{id:"将项目设置为-module",children:["将项目设置为 module",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#将项目设置为-module",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["在 ",(0,s.jsx)(n.strong,{children:"package.json"})," 文件添加"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "type": "module"\n}\n'})}),"\n",(0,s.jsxs)(n.h2,{id:"安装依赖",children:["安装依赖",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#安装依赖",children:"#"})]}),"\n",(0,s.jsxs)(n.div,{className:"rspress-directive tip",children:[(0,s.jsx)(n.div,{className:"rspress-directive-title",children:"TIP"}),(0,s.jsx)(n.div,{className:"rspress-directive-content",children:(0,s.jsxs)(n.p,{children:["总是应该将生产依赖和开发依赖区分,会使 ",(0,s.jsx)(n.code,{children:"node_modules"})," 在生产环境中更小。\n"]})})]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"安装生产依赖"})}),"\n",(0,s.jsx)(c.PackageManagerTabs,{command:"install @gez/core"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"安装开发依赖"})}),"\n",(0,s.jsx)(c.PackageManagerTabs,{command:"install @gez/rspack -D"}),"\n",(0,s.jsxs)(n.h2,{id:"添加脚本",children:["添加脚本",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#添加脚本",children:"#"})]}),"\n",(0,s.jsxs)(n.p,{children:["在 ",(0,s.jsx)(n.strong,{children:"package.json"})," 文件添加"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "scripts": {\n "dev": "gez dev",\n "build": "gez build",\n "start": "gez start",\n "preview": "gez preview",\n "release": "gez release",\n "postinstall": "gez install"\n }\n}\n'})}),"\n",(0,s.jsxs)(n.h2,{id:"入口文件",children:["入口文件",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#入口文件",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"基本结构"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"- src/\n - entry.client.ts # 客户端程序入口,一般会处理水合\n - entry.server.ts # 使用框架的 SSR API 渲染出 HTML 内容\n - entry.node.ts # 创建一个服务器程序,来处理请求\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"srcentryclientts",children:["src/entry.client.ts",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#srcentryclientts",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"模拟水合,更新当前时间"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"const time = document.querySelector('time');\nsetInterval(() => {\n time?.setHTMLUnsafe(new Date().toISOString());\n}, 1000);\n\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"srcentryserverts",children:["src/entry.server.ts",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#srcentryserverts",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"模拟框架的 SSR API,渲染出 HTML 内容返回"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:'// 这里必须使用 import type,否则开发阶段会报错\nimport type { ServerContext } from \'@gez/core\';\n\nexport default async (ctx: ServerContext, params: { url: string }) => {\n // 获取注入的代码\n const script = await ctx.getInjectScript();\n const time = new Date().toISOString();\n ctx.html = `\n\n\n\n \n \n Gez\n\n\n

Gez

\n

Hello world!

\n

URL: ${params.url}

\n \n ${script}\n\n\n`;\n};\n\n'})}),"\n",(0,s.jsxs)(n.h3,{id:"srcentrynodets",children:["src/entry.node.ts",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#srcentrynodets",children:"#"})]}),"\n",(0,s.jsx)(n.p,{children:"创建一个 web 服务器,来处理客户请求"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"import http from 'node:http';\nimport type { GezOptions } from '@gez/core';\n\nexport default {\n // 设置应用的唯一名字,如果有多个项目,则名字不能重复\n name: 'ssr-html',\n // 本地执行 dev 和 build 时会使用\n async createDevApp(gez) {\n return import('@gez/rspack').then((m) =>\n m.createApp(gez, (buildContext) => {\n // 可以在这里修改 Rspack 编译的配置\n })\n );\n },\n async createServer(gez) {\n const server = http.createServer((req, res) => {\n // 静态文件处理\n gez.middleware(req, res, async () => {\n // 传入渲染的参数\n const ctx = await gez.render({\n url: req.url\n });\n // 响应 HTML 内容\n res.end(ctx.html);\n });\n });\n // 监听端口\n server.listen(3005, () => {\n console.log('http://localhost:3005');\n });\n }\n} satisfies GezOptions;\n\n"})}),"\n",(0,s.jsxs)(n.h3,{id:"启动项目",children:["启动项目",(0,s.jsx)(n.a,{className:"header-anchor","aria-hidden":"true",href:"#启动项目",children:"#"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm run dev\n"})}),"\n",(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["浏览器打开:",(0,s.jsx)(n.a,{href:"http://localhost:3005",target:"_blank",rel:"noopener noreferrer",children:"http://localhost:3005"})]}),"\n"]})]})}function d(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}=Object.assign({},(0,t.ah)(),e.components);return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}let i=d;d.__RSPRESS_PAGE_META={},d.__RSPRESS_PAGE_META["guide%2Fstart%2Fgetting-started.mdx"]={toc:[{text:"创建项目",id:"创建项目",depth:2},{text:"将项目设置为 module",id:"将项目设置为-module",depth:2},{text:"安装依赖",id:"安装依赖",depth:2},{text:"添加脚本",id:"添加脚本",depth:2},{text:"入口文件",id:"入口文件",depth:2},{text:"src/entry.client.ts",id:"srcentryclientts",depth:3},{text:"src/entry.server.ts",id:"srcentryserverts",depth:3},{text:"src/entry.node.ts",id:"srcentrynodets",depth:3},{text:"启动项目",id:"启动项目",depth:3}],title:"快速开始",frontmatter:{}}}}]); \ No newline at end of file diff --git a/static/js/async/512.8135c617.js b/static/js/async/512.8135c617.js new file mode 100644 index 00000000..453f876e --- /dev/null +++ b/static/js/async/512.8135c617.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkssr_docs=self.webpackChunkssr_docs||[]).push([["512"],{9790:function(t,e,i){i.r(e),i.d(e,{default:function(){return c}});var n=i(1549),s=i(6603);function a(t){return(0,n.jsx)(n.Fragment,{})}function o(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:e}=Object.assign({},(0,s.ah)(),t.components);return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(a,{...t})}):a(t)}let c=o;o.__RSPRESS_PAGE_META={},o.__RSPRESS_PAGE_META["index.md"]={toc:[],title:"",frontmatter:{pageType:"home",hero:{name:"Gez",text:"基于 ESM 的模块链接。",actions:[{theme:"brand",text:"快速开始",link:"/guide/"},{theme:"alt",text:"GitHub",link:"https://github.com/dp-os/gez"}]},features:[{title:"技术创新",details:"首个基于 ESM 构建的 SSR 多服务模块链接。",icon:"\uD83D\uDC4D"},{title:"项目构建",details:"基于 Rspack 实现,构建速度极快,带给你极致的开发体验。",icon:"\uD83D\uDE80"},{title:"依赖管理",details:"一次构建,一次发布,多服务生效。",icon:"\uD83C\uDFAF"},{title:"同构渲染",details:"支持 Vue2、Vue3、React 等不同框架实现 SSR。",icon:"☁️"},{title:"基准支持",details:"Node20 和支持 ESM dynamic import 和 import.meta 的浏览器。",icon:"\uD83D\uDE0E"},{title:"长久维护",details:"Genesis 从 2020 年迭代至今,现更名为 Gez。",icon:"\uD83D\uDC4F"}]}}}}]); \ No newline at end of file diff --git a/static/js/async/52.3753b1a1.js b/static/js/async/52.3753b1a1.js new file mode 100644 index 00000000..cded2a3a --- /dev/null +++ b/static/js/async/52.3753b1a1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkssr_docs=self.webpackChunkssr_docs||[]).push([["52"],{5:function(e,s,n){n.r(s),n.d(s,{default:function(){return t}});var r=n(1549),i=n(6603);function d(e){let s=Object.assign({h1:"h1",a:"a",p:"p",div:"div",h2:"h2",ul:"ul",li:"li",code:"code",pre:"pre",br:"br",h3:"h3",h4:"h4"},(0,i.ah)(),e.components);return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(s.h1,{id:"模块链接",children:["模块链接",(0,r.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#模块链接",children:"#"})]}),"\n",(0,r.jsx)(s.p,{children:"一个大型项目,总是会拆分成组件库、工具库、业务模块等。它们总是会写在不同的地方,以独立的仓库、monorepo 包等形式存在,但是最终都需要系统的主程序链接这些模块。Gez 的核心功能就是帮你把这些不同地方的模块,快速的链接到一起。实现一个服务发布,其它服务同时更新。"}),"\n",(0,r.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,r.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,r.jsx)(s.div,{className:"rspress-directive-content",children:(0,r.jsx)(s.p,{children:"Gez 默认是支持 SSR 的,你也可以把它当成 CSR 来使用。"})})]}),"\n",(0,r.jsxs)(s.h2,{id:"设计理念",children:["设计理念",(0,r.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#设计理念",children:"#"})]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"我们应该设计一个基础服务,由基础服务提供所有的第三方依赖。"}),"\n",(0,r.jsx)(s.li,{children:"基础服务统一维护第三方依赖更新,一次发布,所有业务系统生效。"}),"\n",(0,r.jsx)(s.li,{children:"业务服务仅构建业务代码,所有的第三方依赖,应指向到基础服务中。"}),"\n"]}),"\n",(0,r.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,r.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,r.jsx)(s.div,{className:"rspress-directive-content",children:(0,r.jsx)(s.p,{children:"由于第三方依赖,都被指向到了基础服务,不再需要重复打包,这会让 Rspack 的编译速度,再提升一个台阶。"})})]}),"\n",(0,r.jsxs)(s.h2,{id:"构建",children:["构建",(0,r.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#构建",children:"#"})]}),"\n",(0,r.jsxs)(s.p,{children:["传统的 SSR 程序在构建目标为 ",(0,r.jsx)(s.code,{children:"node"})," 时,会将 ",(0,r.jsx)(s.code,{children:"node_modules"})," 的模块设置为外部依赖,但是 Gez 会把全部代码都打包成 ESM 模块来进行链接。所以在使用一些第三方依赖的时候,尽可能的选择支持 ESM 的包,否则你可能会遇到一些问题。\n构建完成后,通常你可以看到这样的目录结构。"]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{children:"- dist/ # 构建输出目录\n - client/ # 客户端构建输出\n - chunks/ # 当前服务抽离的公共代码\n - [name].[contenthash].js\n - npm/ # 对外导出的 node_modules 包\n - [name].[contenthash].js\n - src/ # 对外导出的 src 目录下的文件\n - [name].[contenthash].js\n - versions/ # 执行 gez release 命令,会将 client 和 server 的代码打包到这里\n - [contenthash].zip # 压缩文件\n - [contenthash].json # 当前压缩的版本号\n - latest.json # 最新的版本号\n - entry.[contenthash].js # 入口文件\n - importmap.js # 不可缓存文件,执行后往 globalThis 注入 __importmap__ \n - importmap.[contenthash].js # 可缓存文件,执行后往 globalThis 注入 __importmap__ \n - package.json # 声明模块的基本导出信息\n - server/ # 服务端构建输出\n - ... # 除了缺少 versions 目录,其它和 client 目录一致\n"})}),"\n",(0,r.jsxs)(s.div,{className:"rspress-directive tip",children:[(0,r.jsx)(s.div,{className:"rspress-directive-title",children:"TIP"}),(0,r.jsx)(s.div,{className:"rspress-directive-content",children:(0,r.jsxs)(s.p,{children:["使用 ",(0,r.jsx)(s.code,{children:"[contenthash]"})," 可以让我们生成基于内容哈希的文件名,这样我们的静态资产文件就可以放心的设置为强缓存了。",(0,r.jsx)(s.br,{}),"\n"]})})]}),"\n",(0,r.jsxs)(s.h2,{id:"客户端链接",children:["客户端链接",(0,r.jsx)(s.a,{className:"header-anchor","aria-hidden":"true",href:"#客户端链接",children:"#"})]}),"\n",(0,r.jsxs)(s.p,{children:["在服务渲染时注入所有服务的 ",(0,r.jsx)(s.code,{children:"/[服务名]/importmap.[contenthash].js"})," 文件,将模块的哈希映射信息写入到 ",(0,r.jsx)(s.code,{children:"globalThis.__importmap__"})," 对象中,最终将该变量值写入到 ",(0,r.jsx)(s.code,{children:'