はじめに
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 ワークスペースのモノリポジトリのセットアップ
- 共有タイプのパッケージを作成する
- ビルド順序のための TypeScript プロジェクト参照
- ESMモジュール構成
次の記事: PostgreSQL (Drizzle ORM) + MongoDB によるデュアル データベースの設計。