Node.js/TypeScript 包与 monorepo 中是否支持基于目录的自动导出配置?
我太懂这种反复手动写导出的麻烦了——每次新增一个类,既要在文件里加export,又要去index.ts补导出语句,还要更新package.json的exports字段,简直是重复劳动的噩梦!
先直接给结论:原生 Node.js 和 TypeScript 并没有像 Dart 那样完全基于目录结构的自动导出/私有隔离的原生配置,但我们有不少替代方案,能大幅减少手动操作的工作量,甚至实现近似的效果。
一、用工具自动生成「桶文件(Barrel File)」
所谓桶文件就是我们常用的index.ts,它的作用是统一导出目录下的所有模块。手动写太麻烦,但可以用 CLI 工具自动生成和更新:
- 比如
barrelsby这个工具,你可以通过配置文件指定要导出的目录、要排除的私有目录,它会自动扫描文件并生成对应的导出语句。
举个例子,在项目根目录创建barrelsby.json:
然后在{ "directory": ["./src"], "exclude": ["./src/internal"], "delete": true, "format": "esm" }package.json的scripts里加一条命令:
每次新增文件后,运行"scripts": { "generate:barrels": "barrelsby --config barrelsby.json" }npm run generate:barrels,工具就会自动更新所有index.ts的导出语句,完全不用手动写。你还可以把这个命令加到构建脚本的前置步骤,比如"build": "npm run generate:barrels && tsc",确保每次构建前都自动同步导出。
二、用package.json通配符批量配置exports
你不用在exports里手动写每个模块的映射,Node.js 12.7.0+ 支持通配符语法,能批量处理导出路径:
{ "exports": { ".": "./dist/index.js", "./*": "./dist/*.js" }, "typesVersions": { "*": { "*": ["./dist/*.d.ts"] } } }
这样用户导入your-package/ClassA时,Node.js 会自动映射到./dist/ClassA.js,TypeScript 也能通过typesVersions找到对应的类型声明文件。只要你把公开模块放在src根目录(私有代码放在src/internal或src/src这类子目录),就能实现“公开目录自动导出,私有目录无法直接导入”的效果。
三、Monorepo 专属:借助工具链的内置能力
如果你用的是 Nx、TurboRepo 这类现代 monorepo 工具链,它们本身就内置了简化包导出的能力:
- 比如 Nx,每个子包的
tsconfig.lib.json可以配置include和exclude来指定要编译的文件,再结合 Nx 的构建器,能自动处理模块导出和类型映射。你还可以在 monorepo 根目录统一配置barrelsby,给所有子包自动生成桶文件,不用每个包单独设置。 - TurboRepo 则支持在
turbo.json里配置全局任务,比如给所有包统一运行generate:barrels命令,配合工作区的依赖管理,能大幅减少重复配置。
四、有没有类似exportAllModulesAndTypes的单行配置?
遗憾的是,目前 Node.js 和 TypeScript 并没有原生的单一行配置能实现这个需求。但通过上面的工具组合(自动桶文件 + 通配符 exports + TypeScript 类型配置),你完全可以实现近似的效果:把公开代码放在src根目录,私有代码放在src/internal,工具会自动处理所有导出逻辑,你几乎不用手动写任何导出语句。
总结
虽然没有 Dart 那样的原生目录级自动导出,但通过工具链的组合,我们能把手动导出的工作量降到几乎为零。对于 monorepo 来说,用 Nx、TurboRepo 这类工具能进一步统一配置,避免每个子包重复设置。
内容来源于stack exchange

