Published on

配置trpc 以及 trpc-types 共享 | fastify 脚手架项目

Authors
  • avatar
    Name
    Shelton Ma
    Twitter

目录结构

src/
├── trpc/                   # trpc相关
│   ├── routers/            # 存放trpc相关路由
│   │   ├── user.ts         # 用户模块 router
│   │   ├── post.ts         # 帖子模块 router
│   │   └── trpc.ts         # const t = initTRPC.create();
│   │   └── index.ts        # 合并后的 appRouter
│   └── types.ts            # 专门导出给前端用的 AppRouter 类型
├── types/                  # 存放后端需要的类型
│   ├── models/
│   │   ├── user.ts         # User 类型(数据库模型)
│   │   └── post.ts
│   ├── request/
│   │   ├── userRequest.ts  # 某些特殊请求体类型
│   └── response/
│       ├── common.ts       # 通用响应结构定义(比如 BaseResponse)
├── services/               # 后端业务逻辑 service 层
├── utils/                  # 工具类
├── env/                    # 环境变量管理
└── index.ts                # 项目入口

前端如何共享后端 tRPC 的 API 类型定义?

1. 将类型打包成 npm 包, 适合: 项目中长期维护,规范且自动化

  1. src/trpc/types.ts 中导出 export type { AppRouter };

  2. 创建 tsconfig.build.json

    {
      "extends": "./tsconfig.json",
      "compilerOptions": {
        "declaration": true,         // 生成 .d.ts 类型文件
        "emitDeclarationOnly": true, // 只输出类型,不编译 js
        "outDir": "./dist/types",    // 输出目录
        "skipLibCheck": true,
        "stripInternal": true,       // 可选,去掉标了 @internal 的接口
        "composite": true
      },
      "include": [
        "src/trpc/types.ts"           // 只包括你要发布给前端的 types
      ],
      "exclude": [
        "**/*.test.ts",
        "**/*.spec.ts",
        "node_modules"
      ]
    }
    
  3. 添加生成脚本

    // package.json
    "scripts": {
      "build": "tsc",
      "start": "fastify start dist/src/index.js",
      "dev": "tsx src/index.ts",
      "test": "echo \"Error: no test specified\" && exit 1",
      "build:types": "tsc -p tsconfig.build.json"
    }
    
  4. 运行 pnpm run build:types

2. 在dist中配置为npm包

  1. pnpm init

  2. 配置

    {
      "name": "@your-org/trpc-types",
      "version": "1.0.0",
      "main": "dist/index.d.ts",
      "types": "dist/index.d.ts",
      "files": ["dist"],
      "private": false, // 必须是 false,否则不能被安装
      "publishConfig": {
        "registry": "https://npm.pkg.github.com/"
      }
    }
    

3. 将包发布在github私有仓库

  1. 初始化

    cd dist
    git init
    git remote add origin https://github.com/your-org/trpc-types.git
    git add .
    git commit -m "init types"
    git push -u origin main
    
  2. 配置 GitHub Package 作为 npm 源

    1. 在 GitHub 生成一个 Token, generate tokens
    2. 勾选需要访问的仓库

4. 前端使用

  1. 前端项目里创建 .npmrc 文件

    // .npmrc
    @your-org:registry=<https://npm.pkg.github.com/>
    //npm.pkg.github.com/:_authToken=ghp_xxxxxxxxxxxxxxxx
    
  2. 前端安装 pnpm add @your-org/trpc-types

  3. 代码使用

    import type { AppRouter } from '@your-org/trpc-types';
    import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
    
    const trpc = createTRPCProxyClient<AppRouter>({
      links: [httpBatchLink({ url: 'https://api.yourdomain.com/trpc' })],
    });