Skip to content

AI 学习实战系列 · 第一章:环境配置与项目初始化

从零搭建 Node.js + TypeScript 开发环境,为 AI 应用开发铺平道路。

为什么环境配置至关重要

开发 AI 应用离不开 API 调用,而 API 密钥管理、环境变量加载、类型安全校验,这些都是工程化落地的基础。很多初学者在本地跑通 demo 后,上线却遇到各种问题——根因往往就在环境配置上。

本章我们将完成:

  • Node.js 18+ / 20+ LTS 环境准备
  • TypeScript + ES Modules 项目初始化
  • 环境变量安全管理方案(dotenv + Zod)
  • Monorepo 多项目依赖共享

一、项目初始化

1.1 创建项目

bash
mkdir my-ai-app && cd my-ai-app
pnpm init -y

1.2 安装依赖

开发依赖(编译与执行):

bash
pnpm add -D typescript @types/node tsx

生产依赖(环境变量 + 类型校验):

bash
pnpm add dotenv zod

为什么要用 pnpm? 它支持 Monorepo Workspace,多项目共享依赖时无需重复安装,磁盘空间利用率更高。


二、TypeScript 配置

2.1 tsconfig.json

json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "lib": ["ES2022"],
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "resolveJsonModule": true,
    "declaration": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

2.2 配置说明

配置项作用
target编译输出的 JavaScript 版本,ES2022 支持最新特性
module模块系统,ESNext 使用最新 ES Modules
moduleResolution: bundler适用于 Vite/Webpack 等bundler,解析效率更高
strict启用所有严格类型检查,减少运行时错误
skipLibCheck跳过第三方库类型检查,加快编译速度
resolveJsonModule允许直接 import JSON 文件

三、环境变量管理(基础方案)

3.1 dotenv 工作原理

Node.js 默认只识别系统环境变量,不会自动读取 .env 文件。dotenv 的作用是将 .env 文件内容加载到 process.env 中:

.env 文件  →  dotenv.config()  →  process.env

3.2 基础配置实现

创建 .env 文件:

bash
touch .env
env
OPENAI_API_KEY=sk-xxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxx
MINIMAX_API_KEY=xxxxx

配置加载模块:

typescript
// src/config.ts
import { config } from "dotenv"
import { z } from "zod"

config({ path: ".env", override: true })
config({ path: ".env.local", override: true })

const envSchema = z.object({
    API_KEY: z.string(),
    API_BASE_URL: z.string()
})

export const env = envSchema.parse(process.env)

3.3 为什么需要 Zod?

TypeScript 只负责编译期类型检查,而 process.env 中的数据来自外部(.env 文件),编译器无法感知。Zod 在运行时验证数据是否符合预期,确保应用启动前就能发现配置错误。

TypeScript 编译检查  ──→  代码层面类型安全
Zod 运行时验证      ──→  配置层面数据安全

3.4 入口文件验证

typescript
// src/index.ts
import { env } from './config'

console.log(env)

运行 pnpm dev,看到环境变量成功打印即为配置成功。


四、环境变量管理(进阶方案)

当项目需要管理多环境(development / production)时,推荐使用 dotenv-flow + dotenv-expand + Zod 组合。

4.1 多文件加载

.env                        # 基础配置(所有环境共享)
.env.local                  # 本地覆盖,git 忽略
.env.development            # 开发专用
.env.development.local      # 开发本地覆盖(最高优先级)
.env.production             # 生产专用
.env.production.local       # 生产本地覆盖

4.2 进阶配置实现

typescript
// src/base-config.ts
import { config } from "dotenv-flow"
import { expand } from "dotenv-expand"
import { z } from "zod"

expand(config())

const envSchema = z.object({
    API_KEY: z.string(),
    API_BASE_URL: z.string(),
    API_URL: z.string(),
})

export const env = envSchema.parse(process.env)

dotenv-flow 自动按 NODE_ENV 加载对应文件,dotenv-expand 支持 ${VAR} 变量展开语法。

4.3 文件优先级速查

假设 NODE_ENV=development

文件是否加载
.env
.env.local
.env.development
.env.development.local✅(最高)
.env.production

五、Monorepo Workspace 配置

当多个子项目需要共享根目录依赖时,使用 pnpm workspace。

5.1 目录结构

learning-ai/
├── package.json          # 根目录配置
├── pnpm-workspace.yaml   # 工作空间配置
└── src/
    └── stage-01-basics/
        └── code/
            └── 01/       # 子项目
                ├── src/
                └── package.json

5.2 根目录配置

json
{
  "name": "@learning-ai/root",
  "private": true,
  "workspaces": ["src/stage-01-basics/code/*"],
  "dependencies": {
    "@types/node": "^25.5.2",
    "dotenv": "^17.4.1",
    "tsx": "^4.21.0",
    "typescript": "^6.0.2",
    "zod": "^4.3.6"
  }
}
yaml
# pnpm-workspace.yaml
packages:
  - 'src/stage-01-basics/code/*'

5.3 子项目配置

json
{
  "name": "01",
  "type": "module",
  "scripts": {
    "dev": "tsx src/index.ts",
    "build": "tsc"
  }
}

关键点: private: true 防止根目录被发布为 npm 包;子项目无需声明依赖,直接使用根目录安装的包。


六、常见问题速查

问题原因解决方案
ERR_REQUIRE_ESMpackage.json 未设置 "type": "module"添加 "type": "module"
API Key 泄露.env 提交到 git添加到 .gitignore
OPENAI_API_KEY is required.env 未配置或值为空检查 .env 文件
启动无错但 API 失败dotenv 未加载确认 config() 在入口顶部

延伸阅读


下一章我们将学习 LLM API 原生调用,掌握 OpenAI / Anthropic / MiniMax 三大厂商的接口差异。