You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 10:06:21