如何用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')即可直接获取默认导出,无需加.defaultallowSyntheticDefaultImports配合前者,允许从无默认导出的模块中导入默认值,提升跨环境兼容性
3. 验证效果
- ESM环境:
import MyModule from 'your-package'可直接使用 - CJS环境:
const MyModule = require('your-package')可直接使用,无需require('your-package').default
编译与发布
- 执行
npm run build,生成dist/cjs、dist/esm和dist/types三个目录 - 确保
package.json的files字段(若存在)包含dist目录,或直接发布时携带该目录 - 执行
npm publish完成模块发布
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

