如何在TypeScript的package.json中配置exports与子路径实现优雅导入?
如何实现TypeScript npm包的子路径导入?
我首次尝试使用TypeScript创建npm包,目前遇到了一些问题,可能是对文档理解有误。当前使用Node 16.16.0与npm 8.13.2。
项目结构
src/ ├─ module1/ │ ├─ index.ts ├─ module2/ │ ├─ index.ts package.json tsconfig.json
配置文件
tsconfig.json
{ "compilerOptions": { "target": "es2017", "module": "commonjs", "esModuleInterop": true, "declaration": true, "outDir": "./lib", "strict": true }, "include": ["src"], "exclude": ["node_modules", "**/__tests__/*"] }
package.json
{ "name": "@owner/mypackage", "version": "v1.0.0", ... "files": [ "lib/**/*" ], "type": "module", "exports": { "./module1": "./lib/module1/index.js", "./module2": "./lib/module2/index.js", "./package.json": "./package.json" } }
当前问题
发布模块后生成的结构如下:
lib/ ├─ module1/ │ ├─ index.js │ ├─ index.d.ts ├─ module2/ │ ├─ index.js │ ├─ index.d.ts package.json
目前只能通过以下方式导入:
import {Foo} from "@owner/mypackage/lib/module1";
但我希望实现的导入方式是:
import {Foo} from "@owner/mypackage/module1";
请问如何实现该导入模式?是否有可遵循的最佳实践或优化方案?
解决方案
1. 为exports补充类型定义
TypeScript需要明确的类型导出路径,你需要在package.json的exports每个子路径中添加types字段,指向对应的.d.ts文件:
{ "exports": { "./module1": { "types": "./lib/module1/index.d.ts", "import": "./lib/module1/index.js", "require": "./lib/module1/index.js" }, "./module2": { "types": "./lib/module2/index.d.ts", "import": "./lib/module2/index.js", "require": "./lib/module2/index.js" }, "./package.json": "./package.json" } }
2. 统一模块系统配置
你的package.json中设置了"type": "module"(ES模块),但tsconfig.json的module字段是commonjs,这会导致模块系统不匹配,需要调整TS配置:
修改tsconfig.json的compilerOptions:
{ "compilerOptions": { "target": "es2017", "module": "ESNext", // 改为ES模块格式 "moduleResolution": "NodeNext", // 匹配Node.js的模块解析逻辑 "esModuleInterop": true, "declaration": true, "outDir": "./lib", "strict": true }, "include": ["src"], "exclude": ["node_modules", "**/__tests__/*"] }
3. 验证本地导入
修改配置后,先本地构建:
tsc
然后用npm link将包链接到本地测试项目,测试导入语句:
import {Foo} from "@owner/mypackage/module1";
如果能正常导入且类型提示正常,说明配置正确。
最佳实践
- 统一模块系统:尽量保持
package.json的type字段与TS的module、moduleResolution配置一致,避免ES模块和CommonJS混合导致的问题。 - 明确导出所有子路径:在
exports中清晰定义所有可访问的子路径,同时不要遗漏类型文件,确保TypeScript用户能获得完整的类型支持。 - 可选:添加根路径导出:如果需要支持
import { ... } from "@owner/mypackage"的根导入,可以在exports中添加:
同时在".": { "types": "./lib/index.d.ts", "import": "./lib/index.js", "require": "./lib/index.js" }src目录下创建index.ts,统一导出各模块的内容。 - 简化构建流程:可以使用
tsup或rollup等构建工具,自动处理TS编译、类型生成和模块格式转换,减少手动配置的工作量。
内容的提问来源于stack exchange,提问作者Yoshi
相关产品推荐
相关产品推荐

