快速开始

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

TIP

Gez 默认支持 SSR,但是你可以当成 CSR 来使用。

创建项目

1cd 项目目录
2npm init

设置 ESM

package.json
1{
2    "type": "module",
3}

安装依赖

安装生产依赖

npm
yarn
pnpm
bun
1npm install @gez/core

安装开发依赖

npm
yarn
pnpm
bun
1npm install @gez/rspack typescript @types/node -D
TIP

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

添加脚本

package.json
1{
2    "scripts": {
3        "dev": "gez dev",
4        "build": "npm run build:dts && npm run build:ssr",
5        "build:ssr": "gez build",
6        "preview": "gez preview",
7        "start": "gez start",
8        "build:dts": "tsc --declaration --emitDeclarationOnly --outDir dist/src"
9    },
10}
TIP

你需要手动配置 tsconfig.json 文件,否则执行 build:dts 命令会报错。

目录结构

- src/ - entry.client.ts # 客户端渲染入口。 - entry.server.ts # 服务端渲染入口。 - entry.node.ts # 创建服务器。 - tsconfig.json # TS 的配置。 - package.json # 软件包配置。

tsconfig.json

1{
2    "compilerOptions": {
3        "isolatedModules": true,
4        "experimentalDecorators": true,
5        "resolveJsonModule": true,
6        "types": [
7            "@types/node"
8        ],
9        "target": "ESNext",
10        "module": "ESNext",
11        "moduleResolution": "node",
12        "strict": true,
13        "skipLibCheck": true,
14        "allowSyntheticDefaultImports": true,
15        "paths": {
16            "ssr-html/src/*": [
17                "./src/*"
18            ],
19            "ssr-html/*": [
20                "./*"
21            ]
22        }
23    },
24    "include": [
25        "src"
26    ],
27    "exclude": [
28        "dist"
29    ]
30  }
WARNING

你需要将上面的 ssr-html,替换成 package.jsonname 字段的值。

创建服务器

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

src/entry.node.ts
1import http from 'node:http';
2import type { GezOptions } from '@gez/core';
3
4export default {
5    // 本地执行 dev 和 build 时会使用
6    async createDevApp(gez) {
7        return import('@gez/rspack').then((m) =>
8            m.createRspackHtmlApp(gez, {
9                config(context) {
10                    // 可以在这里修改 Rspack 编译的配置
11                }
12            })
13        );
14    },
15    async createServer(gez) {
16        const server = http.createServer((req, res) => {
17            // 静态文件处理
18            gez.middleware(req, res, async () => {
19                // 传入渲染的参数
20                const rc = await gez.render({
21                    params: {
22                        url: req.url
23                    }
24                });
25                // 响应 HTML 内容
26                res.end(rc.html);
27            });
28        });
29        // 监听端口
30        server.listen(3000, () => {
31            console.log('http://localhost:3000');
32        });
33    }
34} satisfies GezOptions;

服务端渲染

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

src/entry.server.ts
1import type { RenderContext } from '@gez/core';
2
3export default async (rc: RenderContext) => {
4    // 提交依赖收集
5    await rc.commit();
6    // 响应 HTML
7    const time = new Date().toISOString();
8    rc.html = `
9<!DOCTYPE html>
10<html>
11<head>
12    ${rc.preload()}
13    <title>Gez</title>
14    ${rc.css()}
15</head>
16<body>
17    <h1>Gez</h1>
18    <h2>Hello world!</h2>
19    <p>URL: ${rc.params.url}</p>
20    <time>${time}</time>
21    ${rc.importmap()}
22    ${rc.moduleEntry()}
23    ${rc.modulePreload()}
24</body>
25</html>
26`;
27};

客户端渲染

更新当前时间

src/entry.client.ts
1const time = document.querySelector('time');
2setInterval(() => {
3    time?.setHTMLUnsafe(new Date().toISOString());
4}, 1000);

启动项目

1npm run dev

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

更多例子

TIP

如果你使用了 Gez,欢迎提交 PR,在这里提供更多的例子。