如何在Monorepo中从CLI包导出API供Web应用调用?
解决Monorepo中CLI包与Web应用共享API的问题
1. 重构CLI包代码结构
将CLI启动逻辑与公共API彻底拆分,避免导入API时触发CLI自动执行:
- 创建
src/cli.ts,迁移原src/index.ts中的CLI初始化代码:// src/cli.ts import { Command } from "commander"; import { info } from "./commands/info"; (async () => { const program = new Command() .name("cli") .addCommand(info); program.parse(); })(); - 创建
src/api.ts,专门导出公共可复用函数:// src/api.ts export { getInfo } from "./commands/info"; - 删除原
src/index.ts,后续用src/cli.ts作为CLI的入口文件。
2. 更新tsup打包配置
修改CLI包的tsup.config.ts,同时打包CLI入口和API入口:
// tsup.config.ts export default defineConfig({ clean: false, dts: true, entry: ["src/cli.ts", "src/api.ts"], // 新增api.ts入口 format: ["esm"], sourcemap: true, target: "esnext", outDir: "dist", });
执行打包后,dist目录会生成cli.js、api.js以及对应的类型声明文件。
3. 配置CLI包的package.json
通过exports字段明确声明子路径导出(ESM包强制要求),解决「Package path not exported」错误:
{ "name": "@pkg/cli", "type": "module", "main": "./dist/cli.js", "exports": { ".": "./dist/cli.js", // 根路径指向CLI入口 "./api": "./dist/api.js" // 子路径/api指向API入口 }, "typesVersions": { "*": { "api": ["./dist/api.d.ts"] // 配置TypeScript类型映射 } } // 其他原有字段... }
4. 在Web应用中导入使用
现在可以直接通过指定路径导入公共API,且不会触发CLI的自动执行逻辑:
// apps/web/src/任意文件.ts import { getInfo } from "@pkg/cli/api"; getInfo(); // 正常输出"Hello there"
内容的提问来源于stack exchange,提问作者nehalist
相关产品推荐
相关产品推荐

