为什么我们使用别名导入导出
在 BestMCP 项目中,我们广泛使用 TypeScript 路径别名来简化模块导入。当你查看源码时,会发现几乎所有文件都使用别名进行导入/导出,而不是相对路径。
import { ToolNotFoundError, ToolValidationError } from "@server/errors";
import type { ToolMetadata } from "@server/types";
import { BestMCP, Tool, Param } from "bestmcp";为什么使用别名
1. 代码可维护性
别名提供了稳定的导入路径,不随文件位置变化而改变。当你重构代码、移动文件或重组目录结构时,使用别名的导入语句无需修改。
相对路径的问题:
// ❌ 使用相对路径 - 脆弱且难以维护
import { Server } from "../../../server";
import { validateSchema } from "../utils/validation";
import { TransportManager } from "./transport-manager";别名的优势:
// ✅ 使用别名 - 稳定且清晰
import { Server } from "@server/server";
import { validateSchema } from "@server/utils/validation";
import { TransportManager } from "@server/transport-manager";2. 提高代码可读性
别名让导入路径更加语义化,能够清楚地表明模块的来源和用途:
@server/*- 来源于核心库的模块@bestmcp/server- 核心库的主入口bestmcp- 根级别包的公共 API
3. 避免相对路径混乱
在复杂的 monorepo 结构中,相对路径可能变得非常复杂且难以理解:
// 没有别名时可能出现的情况
import { SomeClass } from "../../../../../packages/server/src/utils/some-class";使用别名后,这种混乱的情况被完全消除。
4. 重构友好
当你需要将代码块复制到其他文件,或者批量移动文件时,别名导入不需要任何修改,而相对路径导入则需要手动调整每个路径。
我们的别名系统
BestMCP 项目使用以下三种主要别名:
@server/*
映射关系:
"@server/*": ["packages/server/src/*"]用途: 用于核心库内部模块的绝对路径导入
使用场景:
// 核心库内部模块之间的导入
import { Server } from "@server/server";
import { TransportManager } from "@server/transport-manager";
import { validateSchema } from "@server/utils/validation";
import { ToolNotFoundError } from "@server/errors";
import type { ToolMetadata } from "@server/types";@bestmcp/server
映射关系:
"@bestmcp/server": ["packages/server/src"]用途: 核心库的主入口点,用于从外部导入核心库
使用场景:
// 从根级别或示例项目中导入核心库
import * as BestMCP from "@bestmcp/server";
import { BestMCP as BestMCPClass } from "@bestmcp/server";bestmcp
映射关系:
"bestmcp": ["packages/bestmcp/src"]用途: 根级别包的入口,主要用于示例项目和外部使用
使用场景:
// 示例项目中的导入
import { BestMCP, Tool, Param } from "bestmcp";配置说明
TypeScript 配置 (config/tsconfig.json)
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@server/*": ["packages/server/src/*"],
"@bestmcp/server": ["packages/server/src"],
"@bestmcp/server/*": ["packages/server/src/*"],
"bestmcp": ["packages/bestmcp/src"],
"bestmcp/*": ["packages/bestmcp/src/*"]
}
}
}Vitest 配置 (config/vitest.config.ts)
export default defineConfig({
test: {
alias: {
"@server": path.resolve(__dirname, "packages/server/src"),
"@bestmcp/server": path.resolve(__dirname, "packages/server/src"),
bestmcp: path.resolve(__dirname, "packages/bestmcp/src"),
},
},
resolve: {
alias: {
"@server": path.resolve(__dirname, "packages/server/src"),
"@bestmcp/server": path.resolve(__dirname, "packages/server/src"),
bestmcp: path.resolve(__dirname, "packages/bestmcp/src"),
},
},
});添加新别名
如果你需要添加新的路径别名,需要同时修改以下文件:
1. 更新 TypeScript 配置
在 config/tsconfig.json 中添加新的路径映射:
{
"compilerOptions": {
"paths": {
// 现有别名...
"@new-alias/*": ["path/to/new/module/*"]
}
}
}2. 更新 Vitest 配置
在 config/vitest.config.ts 中添加对应的别名解析:
export default defineConfig({
test: {
alias: {
// 现有别名...
"@new-alias": path.resolve(__dirname, "path/to/new/module"),
},
},
resolve: {
alias: {
// 现有别名...
"@new-alias": path.resolve(__dirname, "path/to/new/module"),
},
},
});3. 验证配置
运行以下命令确保配置正确:
# 类型检查
pnpm type:check
# 运行测试
pnpm test
# 代码格式检查
pnpm check:fix最佳实践
1. 保持一致性
在整个项目中保持别名使用的一致性,不要混用相对路径和别名导入。
2. 语义化命名
选择能够清楚表达模块用途的别名名称。
3. 避免过度嵌套
不要创建过于深层或复杂的别名结构。
4. 文档同步
当你添加新别名时,记得更新相关文档和配置说明。
5. IDE 支持
确保你的 IDE 支持 TypeScript 路径别名配置,大多数现代 IDE (如 VS Code) 会自动识别 config/tsconfig.json 中的路径配置。
Last updated on