首页 / 资讯中心 / 文章详情

从0到1打造接单脚手架02:用NestJS+TypeScript完成项目搭建与TaoToken接入

从0到1打造接单脚手架02:用NestJS+TypeScript完成项目搭建与TaoToken接入 ★ FEATURED ARTICLE
1. 接单脚手架为什么先搭骨架再谈业务接单这件事最怕的不是需求难而是每来一个单子都要从零起项目。我接过几个小单之后发现真正吃掉时间的不是写业务代码而是环境、目录、配置、接口通道这些重复劳动。所以这一篇的目标很明确用 NestJS TypeScript 搭一个能反复复用的工程骨架把 npm 依赖、git 版本管理、模块目录规划一次定好并且预留一个统一的 API 通道配置位后面接大模型能力时不用再改结构。NestJS 是什么简单说它是 Node.js 上的一个后端框架自带模块化、依赖注入和装饰器语法写起来像 Angular 那套思路但跑在服务端。它能做什么帮你把 controller、service、module 分层管好接单项目里常见的用户、订单、支付、回调这些模块可以各占一个目录互不打架。适合谁适合已经会一点 TypeScript、想接私活但不想每次重搭环境的人。TypeScript 则是给 JavaScript 加了类型接单时改需求频繁类型能帮你提前发现拼错字段这类低级错误。这一篇我会按真实操作顺序走先确认 Node.js 和 npm再初始化 NestJS 工程然后规划目录、写 tsconfig 和 .env最后启动服务并做一次接口连通性检查。中间会顺带把统一 API 通道的配置位留出来这样下一篇接具体能力时直接填 Key 就行。整个过程你可以在自己的机器上跟着敲命令和配置我都会给全。需要提前说明的是脚手架的价值在于“稳定可复制”。我试过把配置散落在各个文件里结果换台机器就启动不起来。所以下面所有关键参数都会集中到 .env 和 config 目录代码里只读配置不写死。这样你接单交付时客户换环境也只需要改一个文件。2. 环境准备与 NestJS 工程初始化2.1 确认 Node.js 与 npm 版本第一步永远是确认运行时。打开终端输入下面两条命令node -v npm -v我这边实测输出是v22.x和10.x。Node.js 建议用 20 以上的 LTS 版本NestJS 新版本对 Node 版本有要求太低会报奇怪的语法错误。如果你还没装去 Node.js 官网下载对应系统的安装包一路下一步即可npm 会随 Node 一起装上。装完如果node -v提示找不到命令多半是环境变量没生效。Windows 下关掉终端重新开一个macOS/Linux 下确认安装路径进了 PATH。这一步别跳过后面 nest 命令依赖它。2.2 安装 NestJS CLI 并创建工程NestJS 提供了命令行工具来生成工程。全局装一次npm install -g nestjs/cli装完验证nest --version然后建一个工程目录比如jiedan-admin进入后初始化mkdir jiedan-admin cd jiedan-admin nest new .执行nest new .时它会问你用哪个包管理器选 npm。它会自动拉依赖并生成基础结构。如果你在空目录里执行报错可以换成npx --yes nestjs/cli new .让 npx 临时拉取 CLI 再执行避免全局命令路径问题。初始化完成后目录里会出现src、test、package.json、tsconfig.json等文件。先别急着改我们下一步规划目录。2.3 git 版本管理与首次提交接单项目一定要有 git不然改崩了没法回退。先确认git --version如果没有去 git 官网下载安装。Windows 安装后如果命令行还是找不到 git需要把 git 的 cmd 目录加进 PATH比如setx PATH %PATH%;D:\Program Files\Git\cmd关掉终端重开再验证。git 可用后在工程根目录初始化并提交git init git add . git commit -m chore: init nestjs scaffold建议顺手加一个.gitignore把node_modules、dist、.env排除掉。.env里有密钥绝对不能提交。这一步做完你的骨架就有了版本基线后面每加一个模块提交一次接单交付时也方便给客户看提交记录。3. 目录规划与统一 API 通道配置位3.1 模块目录结构设计NestJS 默认把业务都塞在src下接单项目模块一多就乱。我习惯按职责分目录下面是我在用的结构src/ ├── common/ # 通用工具、拦截器、过滤器 │ ├── filters/ │ └── interceptors/ ├── config/ # 配置读取与校验 │ └── configuration.ts ├── modules/ # 业务模块 │ ├── health/ # 健康检查 │ └── ai/ # 统一 API 通道模块预留 ├── app.module.ts └── main.tsmodules/ai就是给统一 API 通道预留的位置。后面接大模型能力时所有请求都从这里出去业务模块只调 service不直接碰外部接口。这样换供应商时只改一个地方。3.2 tsconfig 关键配置NestJS 生成的tsconfig.json基本够用但接单项目我建议确认几个字段保证路径别名和严格模式{ compilerOptions: { module: commonjs, declaration: true, removeComments: true, emitDecoratorMetadata: true, experimentalDecorators: true, allowSyntheticDefaultImports: true, target: ES2021, sourceMap: true, outDir: ./dist, baseUrl: ./, incremental: true, strictNullChecks: true, noImplicitAny: true, strictBindCallApply: true, forceConsistentCasingInFileNames: true, noFallthroughCasesInSwitch: true, paths: { /*: [src/*] } } }paths里的/*是路径别名导入时写/common/filters比../../common/filters清爽很多。strictNullChecks和noImplicitAny打开后接单改需求时能少踩空指针的坑。3.3 .env 与统一 API 通道配置统一 API 通道的核心是把地址和密钥集中管理。在根目录建.env# 服务端口 PORT3000 # 统一 API 通道配置位 AI_BASE_URLhttps://taotoken.net/api AI_API_KEYyour_api_key_here AI_MODEL_IDyour_model_id_here再建一个.env.example把值留空提交到 git 给客户做参考。然后在src/config/configuration.ts里读取export default () ({ port: parseInt(process.env.PORT ?? 3000, 10), ai: { baseUrl: process.env.AI_BASE_URL ?? https://taotoken.net/api, apiKey: process.env.AI_API_KEY ?? , modelId: process.env.AI_MODEL_ID ?? , }, });这里三个字段 Base URL、Key、Model ID 就是统一通道的三件套。Base URL 固定指向https://taotoken.net/apiKey 和 Model ID 从环境变量注入。业务代码里通过ConfigService读取不写死任何值。这样你接单交付时客户只要改.env就能换成自己的配置。注意.env必须进.gitignore.env.example才提交。密钥泄露是接单里最容易翻车的地方。4. 启动验证与接口连通性检查4.1 安装配置依赖并启动NestJS 读 .env 需要装配置模块npm install nestjs/config然后在app.module.ts里注册import { Module } from nestjs/common; import { ConfigModule } from nestjs/config; import configuration from ./config/configuration; import { HealthModule } from ./modules/health/health.module; Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, load: [configuration], }), HealthModule, ], }) export class AppModule {}启动开发模式npm run start:dev看到Nest application successfully started就说明骨架跑起来了。默认监听 3000 端口。4.2 健康检查接口验证在src/modules/health下建一个 controller返回服务状态和配置是否读到import { Controller, Get } from nestjs/common; import { ConfigService } from nestjs/config; Controller(health) export class HealthController { constructor(private readonly config: ConfigService) {} Get() check() { return { status: ok, aiBaseUrl: this.config.getstring(ai.baseUrl), hasApiKey: Boolean(this.config.getstring(ai.apiKey)), }; } }用 curl 验证curl http://localhost:3000/health预期返回类似{ status: ok, aiBaseUrl: https://taotoken.net/api, hasApiKey: true }hasApiKey为 true 说明 .env 读到了统一通道配置位生效。如果为 false检查.env是否在根目录、ConfigModule是否isGlobal: true。4.3 统一通道连通性检查配置位有了还要确认通道本身能通。在modules/ai下写一个 service用 Node 内置 fetch 发一次请求import { Injectable } from nestjs/common; import { ConfigService } from nestjs/config; Injectable() export class AiService { constructor(private readonly config: ConfigService) {} async ping() { const baseUrl this.config.getstring(ai.baseUrl); const apiKey this.config.getstring(ai.apiKey); const res await fetch(${baseUrl}/v1/models, { headers: { Authorization: Bearer ${apiKey} }, }); return { status: res.status, ok: res.ok }; } }暴露一个接口调用它访问后如果返回ok: true说明 Base URL 和 Key 都对。这一步是接单项目里最关键的连通性检查通道不通后面全白搭。Key 的获取和具体模型调用下一篇会展开这里先把通道打通。5. 本篇常见报错排查5.1 401 Unauthorized这是最常见的。返回 401 说明 Key 没传对或没读到。先看/health里hasApiKey是不是 true如果是 false就是.env没被加载。检查三点.env是否在项目根目录、ConfigModule.forRoot是否调用了、启动命令的工作目录对不对。如果hasApiKey是 true 但请求仍 401那就是 Key 本身无效或过期去控制台重新生成一个。5.2 local proxy failed这个报错通常出现在请求发不出去的时候提示本地代理失败。先确认你的网络环境能正常访问外网再检查AI_BASE_URL有没有多写斜杠或拼错。比如写成https://taotoken.net/api/末尾带斜杠拼接/v1/models时可能变成双斜杠导致路由不匹配。统一去掉末尾斜杠。另外确认没有在系统里配置奇怪的全局代理变量HTTP_PROXY这类环境变量如果指向一个不可用的地址fetch 会直接失败。5.3 reading choices 报错这个报错一般出现在解析响应时代码里写了response.choices[0]但实际返回结构不是预期格式。原因通常是请求体格式不对或者模型 ID 填错导致返回了错误对象。先打印完整响应体看结构确认AI_MODEL_ID和通道支持的模型一致。解析前加一层判断if (!data || !Array.isArray(data.choices)) { throw new Error(unexpected response: ${JSON.stringify(data)}); }这样报错信息更清楚不会只丢一个reading choices。5.4 OAuth 相关报错如果你用的是需要 OAuth 授权的客户端工具可能会遇到 token 过期或回调失败。这类问题多半是授权流程没走完或者本地回调端口被占用。先确认授权时填的 Base URL 和 Key 与.env一致再检查回调地址的端口有没有被其他进程占用。重新走一遍授权流程通常能解决。如果工具支持手动填 Key直接填 Key 比走 OAuth 更省事。5.5 端口占用与启动失败npm run start:dev报EADDRINUSE说明 3000 端口被占。改.env里的PORT换一个或者找到占用进程杀掉。macOS/Linux 用lsof -i :3000Windows 用netstat -ano | findstr :3000。改完端口记得同步更新 curl 验证的地址。6. 把骨架变成可复用资产到这里一个能反复用的接单骨架就成型了NestJS TypeScript 打底npm 管依赖git 管版本模块目录分好统一 API 通道的 Base URL、Key、Model ID 三件套集中在 .env 里。下次接新单直接复制这个目录改个名字就能开工省下的时间全花在业务上。统一通道的配置位已经留好Key 的申请和具体模型调用你可以先去 TaoToken 的 API Keys 页面拿到密钥再对照接入文档把参数填进.env。如果只是想先验证模型通不通用模型对话页面发一条消息最快。长期做编码类接单、需要跑 Agent 任务的可以看下 Coding Plan把通道能力用满。骨架搭好只是开始下一篇我们在这个骨架上接第一个真实业务模块。
阅读完成 · 觉得有帮助?
咨询建站