Admin.js+Nest.js混合ESM/CJS Monorepo共享模块配置求助
Monorepo 跨 ESM/CJS 共享模块配置方案
针对你的场景(ESM的adminjs、CJS的api、共享Nest/Mongoose代码的shared模块),以下是可直接复用的配置示例:
项目结构
monorepo-root/ ├── adminjs/ │ ├── src/ │ ├── package.json │ └── tsconfig.json ├── api/ │ ├── src/ │ ├── package.json │ └── tsconfig.json ├── shared/ │ ├── src/ │ │ ├── index.ts │ │ ├── schemas/ │ │ └── utils/ │ ├── package.json │ ├── tsconfig.base.json │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ └── tsconfig.types.json └── package.json (根目录,用于管理workspace)
根目录package.json需要开启workspace:
{ "private": true, "workspaces": ["adminjs", "api", "shared"] }
shared模块配置
这是核心,需要同时输出CJS、ESM和类型文件,通过Node.js条件导出区分不同导入方式。
shared/package.json
{ "name": "@monorepo/shared", "version": "1.0.0", "private": true, "type": "commonjs", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/types/index.d.ts", "exports": { ".": { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js", "types": "./dist/types/index.d.ts" }, "./schemas/*": { "import": "./dist/esm/schemas/*.js", "require": "./dist/cjs/schemas/*.js", "types": "./dist/types/schemas/*.d.ts" }, "./utils/*": { "import": "./dist/esm/utils/*.js", "require": "./dist/cjs/utils/*.js", "types": "./dist/types/utils/*.d.ts" } }, "scripts": { "build": "npm run build:cjs && npm run build:esm && npm run build:types", "build:cjs": "tsc -p ./tsconfig.cjs.json", "build:esm": "tsc -p ./tsconfig.esm.json", "build:types": "tsc -p ./tsconfig.types.json" }, "dependencies": { "@nestjs/common": "^7.6.18", "@nestjs/mongoose": "^7.2.4", "mongoose": "^6.12.0" }, "devDependencies": { "typescript": "^4.9.5" } }
shared/tsconfig.base.json (基础配置)
{ "compilerOptions": { "target": "ES2019", "lib": ["ES2019"], "experimentalDecorators": true, "emitDecoratorMetadata": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "declaration": true, "declarationMap": true, "sourceMap": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
shared/tsconfig.cjs.json (CJS编译配置)
{ "extends": "./tsconfig.base.json", "compilerOptions": { "module": "CommonJS", "moduleResolution": "Node", "outDir": "./dist/cjs", "declaration": false } }
shared/tsconfig.esm.json (ESM编译配置)
{ "extends": "./tsconfig.base.json", "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "outDir": "./dist/esm", "declaration": false, "target": "ES2020" } }
shared/tsconfig.types.json (单独编译类型)
{ "extends": "./tsconfig.base.json", "compilerOptions": { "module": "ESNext", "outDir": "./dist/types", "emitDeclarationOnly": true } }
adminjs模块配置 (ESM)
因为adminjs仅支持ESM,需确保所有配置匹配:
adminjs/package.json
{ "name": "@monorepo/adminjs", "version": "1.0.0", "private": true, "type": "module", "scripts": { "build": "nest build", "start": "nest start" }, "dependencies": { "@monorepo/shared": "workspace:*", "@adminjs/nestjs": "^5.1.0", "@adminjs/express": "^5.1.0", "@nestjs/common": "^7.6.18", "@nestjs/core": "^7.6.18", "reflect-metadata": "^0.1.13", "rxjs": "^6.6.7" }, "devDependencies": { "@nestjs/cli": "^7.6.0", "typescript": "^4.9.5" } }
adminjs/tsconfig.json
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "target": "ES2020", "experimentalDecorators": true, "emitDecoratorMetadata": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "outDir": "./dist", "declaration": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
api模块配置 (CJS)
保持原有CJS支持:
api/package.json
{ "name": "@monorepo/api", "version": "1.0.0", "private": true, "type": "commonjs", "scripts": { "build": "nest build", "start": "nest start" }, "dependencies": { "@monorepo/shared": "workspace:*", "@nestjs/common": "^7.6.18", "@nestjs/core": "^7.6.18", "@nestjs/mongoose": "^7.2.4", "mongoose": "^6.12.0", "reflect-metadata": "^0.1.13", "rxjs": "^6.6.7" }, "devDependencies": { "@nestjs/cli": "^7.6.0", "typescript": "^4.9.5" } }
api/tsconfig.json
{ "compilerOptions": { "module": "CommonJS", "moduleResolution": "Node", "target": "ES2019", "experimentalDecorators": true, "emitDecoratorMetadata": true, "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "resolveJsonModule": true, "outDir": "./dist", "declaration": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
参考配置逻辑
可以参考Nest官方生态模块的配置思路,比如@nestjs/mongoose这类同时支持CJS和ESM的包,核心都是通过exports字段做条件导出,分开编译两种模块格式。
内容的提问来源于stack exchange,提问作者PikaPuka
相关产品推荐
相关产品推荐

