簡介
Monorepo 允許管理儲存庫中的所有套件 - 共用類型、建置順序和原子變更。本文將引導您從頭開始完成設定。
1.初始化Monorepo
1.1 原始Package.json
{
"name": "xclaw",
"private": true,
"type": "module",
"workspaces": [
"packages/*",
"packages/channels/*"
],
"scripts": {
"build": "npm run build --workspaces --if-present",
"dev": "concurrently \"npm run dev:server\" \"npm run dev:web\"",
"dev:server": "npm run dev -w @xclaw-ai/server",
"dev:web": "npm run dev -w @xclaw-ai/web",
"test": "vitest",
"lint": "eslint packages/*/src"
},
"engines": {
"node": ">=20.0.0",
"npm": ">=10.0.0"
}
}
1.2 建立套件結構
mkdir -p packages/{shared,core,db,gateway,server,integrations,domains,skills,ml,web}/src
2. 共享套件-基礎類型
2.1 套件/共享/package.json
{
"name": "@xclaw-ai/shared",
"version": "1.0.0",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc -b",
"dev": "tsc -b --watch"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
}
}
2.2 共享類型
// packages/shared/src/types/agent.ts
export interface AgentConfig {
id: string;
name: string;
persona: string;
systemPrompt?: string;
llm: LLMConfig;
maxToolIterations: number;
}
export interface LLMConfig {
provider: string;
model?: string;
apiKey?: string;
baseUrl?: string;
temperature?: number;
maxTokens?: number;
}
export interface LLMMessage {
role: 'system' | 'user' | 'assistant' | 'tool';
content: string;
images?: string[];
toolCalls?: ToolCall[];
toolCallId?: string;
}
export interface LLMResponse {
content: string;
toolCalls?: ToolCall[];
usage?: { promptTokens: number; completionTokens: number; totalTokens: number };
finishReason?: 'stop' | 'tool_calls' | 'length';
}
// packages/shared/src/types/tools.ts
export interface ToolDefinition {
name: string;
description: string;
parameters: {
type: 'object';
properties: Record<string, {
type: string;
description: string;
enum?: string[];
}>;
required?: string[];
};
sandbox?: { required: boolean };
}
export interface ToolCall {
id: string;
name: string;
arguments: Record<string, unknown>;
}
export interface ToolResult {
toolCallId: string;
success: boolean;
result: unknown;
error?: string;
duration: number;
}
// packages/shared/src/types/streaming.ts
export type StreamEvent =
| { type: 'text-delta'; delta: string }
| { type: 'tool-call-start'; toolCallId: string; toolName: string }
| { type: 'tool-call-args'; toolCallId: string; args: string }
| { type: 'tool-call-end'; toolCallId: string }
| { type: 'tool-result'; toolCallId: string; result: ToolResult }
| { type: 'finish'; usage?: LLMResponse['usage'] }
| { type: 'error'; error: string };
3. TypeScript 專案參考
3.1 根 tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"isolatedModules": true
}
}
3.2 套件級 tsconfig
// packages/core/tsconfig.json
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"composite": true
},
"include": ["src"],
"references": [
{ "path": "../shared" },
{ "path": "../db" }
]
}
3.3 建置順序
shared (0 deps)
↓
db (depends on shared)
↓
core (depends on shared, db)
↓
integrations (depends on shared, core)
domains (depends on shared, core)
ml (depends on shared, core)
↓
skills (depends on shared, core)
skill-hub (depends on shared, core, skills)
↓
gateway (depends on shared, db, core, integrations, domains, skills)
↓
server (depends on all)
4. npm 工作區指令
# Install dependencies cho tất cả packages
npm install
# Build tất cả packages theo dependency order
npm run build
# Chạy script trong package cụ thể
npm run dev -w @xclaw-ai/server
# Thêm dependency vào package
npm install hono -w @xclaw-ai/gateway
# Thêm internal dependency
# (npm workspaces tự link qua symlinks)
npm install @xclaw-ai/shared -w @xclaw-ai/core
5.ESM 配置
xClaw 完全使用 ESM(ECMAScript 模組):
// ✅ ESM imports — phải có .js extension
import { Agent } from './agent/agent.js';
import { LLMRouter } from '../llm/llm-router.js';
import type { AgentConfig } from '@xclaw-ai/shared';
// ❌ CommonJS — KHÔNG dùng
// const { Agent } = require('./agent');
重要提示: 導入路徑必須存在 .js 即使來源檔案是副檔名 .ts。 TypeScript 編譯器將會正確解析。
6. 總結
您已經了解:
- 設定 npm 工作區 monorepo
- 建立共享類型包
- 用於建置順序的 TypeScript 專案參考
- ESM模組配置
下一篇: 使用 PostgreSQL (Drizzle ORM) + MongoDB 設計雙資料庫。