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

如何用TypeScript创建支持CJS和ESM的npm模块及配置

配置指南:发布兼容CJS/ESM的TypeScript npm模块

一、package.json 核心配置

{
  "name": "your-package-name",
  "version": "1.0.0",
  "description": "你的TypeScript模块描述",
  "main": "./dist/cjs/index.js",
  "module": "./dist/esm/index.js",
  "types": "./dist/types/index.d.ts",
  "exports": {
    ".": {
      "require": "./dist/cjs/index.js",
      "import": "./dist/esm/index.js",
      "types": "./dist/types/index.d.ts"
    }
  },
  "scripts": {
    "build": "npm run build:cjs && npm run build:esm",
    "build:cjs": "tsc -p tsconfig.cjs.json",
    "build:esm": "tsc -p tsconfig.esm.json"
  },
  "keywords": ["typescript", "cjs", "esm"],
  "author": "",
  "license": "MIT"
}
  • exports 是核心配置,明确指定不同导入方式对应的入口文件,比单独的main/module更精准,避免导入歧义
  • types 字段指向生成的类型声明文件,为TypeScript用户提供类型提示

二、tsconfig.cjs.json(CommonJS编译配置)

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "CommonJS",
    "outDir": "./dist/cjs",
    "declaration": false,
    "declarationDir": "./dist/types"
  },
  "include": ["src/**/*"]
}
  • module: "CommonJS" 指定编译输出为CJS格式
  • outDir 将编译产物输出到dist/cjs,和ESM产物目录区分开
  • 关闭declaration,让ES编译流程统一生成类型声明,避免重复

三、tsconfig.esm.json(ES Module编译配置)

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "ESNext",
    "outDir": "./dist/esm",
    "declaration": true,
    "declarationDir": "./dist/types",
    "moduleResolution": "NodeNext"
  },
  "include": ["src/**/*"]
}
  • module: "ESNext" 编译输出为ESM格式,支持现代import语法
  • declaration: true 开启类型声明生成,输出到dist/types目录,供CJS和ESM模块共用
  • moduleResolution: "NodeNext" 让TypeScript正确解析ESM模块的导入逻辑

四、解决默认导出无需.default访问的问题

1. 源码写法

在src/index.ts中使用export default导出核心内容:

const MyModule = {
  sayHello: () => console.log("Hello from my package!")
};

export default MyModule;

2. 根tsconfig.json优化配置

在根目录的tsconfig.json中添加以下配置,确保编译后的CJS模块兼容直接require:

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
  }
}
  • esModuleInterop: true 让TypeScript在编译CJS时自动添加兼容代码,用户用require('your-package')即可直接获取默认导出,无需加.default
  • allowSyntheticDefaultImports 配合前者,允许从无默认导出的模块中导入默认值,提升跨环境兼容性

3. 验证效果

  • ESM环境:import MyModule from 'your-package' 可直接使用
  • CJS环境:const MyModule = require('your-package') 可直接使用,无需require('your-package').default

编译与发布

  1. 执行npm run build,生成dist/cjs、dist/esm和dist/types三个目录
  2. 确保package.json的files字段(若存在)包含dist目录,或直接发布时携带该目录
  3. 执行npm publish完成模块发布

内容的提问来源于stack exchange,提问作者Paul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 01:40:25