如何在npm monorepo的package.json中直接解析到TypeScript源码?
配置npm Monorepo实现本地直接解析.ts文件,发布用编译产物
核心思路
本地开发时让所有工具直接读取src下的原始.ts文件,发布时自动切换到dist目录的编译产物。利用package.json的exports字段做条件指向,配合prepack/postpack脚本解决npm不支持发布时覆盖字段的问题。
本地开发配置(子包package.json)
用exports字段统一指定源码路径,同时配置types指向.ts文件,避免工具加载dist下的.d.ts:
{ "name": "@your-monorepo/pkg-a", "exports": { ".": { "types": "./src/index.ts", "import": "./src/index.ts", "require": "./src/index.ts" } }, "types": "./src/index.ts", "scripts": { "build": "tsc --project tsconfig.json" } }
各工具适配细节
- VSCode:根目录
tsconfig.json开启"composite": true,子包tsconfig.json配置"references"指向依赖的子包,让IDE直接解析跨包TS依赖,无需预构建.d.ts。 - ts-node/tsx:根目录
tsconfig.json添加ts-node配置确保路径解析正常:{ "ts-node": { "require": ["tsconfig-paths/register"] } } - Vite:在
vite.config.ts中排除本地子包的预构建,强制读取源码:export default defineConfig({ optimizeDeps: { exclude: ['@your-monorepo/pkg-a', '@your-monorepo/pkg-b'] } }) - Jest(ts-jest):配置
transformIgnorePatterns不忽略本地子包,让ts-jest直接编译源码:module.exports = { transform: { '^.+\\.tsx?$': 'ts-jest' }, transformIgnorePatterns: ['/node_modules/(?!@your-monorepo/)'] } - tsc:根目录
tsconfig.json开启"composite": true,子包tsconfig.json设置"outDir": "./dist",执行tsc --build时编译到dist,但本地开发无需提前构建。
发布时的产物替换方案
因为npm不支持publishConfig覆盖main/exports,用脚本在发布前临时修改配置,发布后恢复:
方案1:用Node脚本修改package.json
在子包目录下创建scripts/文件夹,添加两个脚本:
replace-exports.js(prepack执行):const fs = require('fs'); const pkg = require('../package.json'); // 保存原始配置 pkg._originalExports = pkg.exports; pkg._originalTypes = pkg.types; // 替换为发布用的dist路径 pkg.exports = { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs" } }; pkg.types = "./dist/index.d.ts"; fs.writeFileSync('../package.json', JSON.stringify(pkg, null, 2));restore-exports.js(postpack执行):const fs = require('fs'); const pkg = require('../package.json'); // 恢复原始配置 pkg.exports = pkg._originalExports; pkg.types = pkg._originalTypes; delete pkg._originalExports; delete pkg._originalTypes; fs.writeFileSync('../package.json', JSON.stringify(pkg, null, 2));
然后更新子包package.json的scripts:
{ "scripts": { "build": "tsc --project tsconfig.json", "prepack": "npm run build && node scripts/replace-exports.js", "postpack": "node scripts/restore-exports.js" } }
方案2:维护独立的发布配置文件
创建package.publish.json,专门用于发布时的配置:
{ "name": "@your-monorepo/pkg-a", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/index.cjs" } }, "main": "./dist/index.cjs", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "files": ["dist", "README.md"] }
然后添加发布脚本:
{ "scripts": { "build": "tsc --project tsconfig.json", "publish:pkg": "npm run build && cp package.publish.json package.json && npm publish && git checkout package.json" } }
避坑提示
- 在
.gitignore中添加dist/,避免误提交编译产物。 - 子包
package.json的files字段默认包含所有文件,发布前需确保只包含dist和必要文档(可在prepack脚本中修改files字段)。
内容的提问来源于stack exchange,提问作者cefn
相关产品推荐
相关产品推荐

