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

同时配置main与module字段能否实现ESM/CJS双兼容?是否需用exports?

库同时兼容ESM和CJS的配置方案解析

现有配置是否可行?能否同时存在main和module字段?

你的现有配置是可行的,而且main和module字段完全可以同时存在:

  • main是Node.js和传统打包工具识别的CJS入口,指向dist/tracking.cjs后,CJS环境(比如用require()加载的代码)会优先读取这个文件。
  • module是Rollup、Webpack等现代打包工具识别的ESM入口,用于Tree-shaking这类优化,ESM环境下打包工具会优先选择这个文件。
  • 你设置的"type": "module"会让项目中默认的.js文件被当作ESM处理,但CJS入口用了.cjs后缀,Node.js会自动识别该后缀为CJS模块,不会和type字段冲突,这部分逻辑是通顺的。

需要注意:纯Node.js运行时(非打包工具场景),用import加载你的库时,默认不会识别module字段,此时要让Node.js精准区分ESM和CJS入口,就得结合条件导出配置。

条件导出exports是否有必要?

非常有必要,它是Node.js官方推荐的现代模块入口配置方式,相比main+module组合有几个核心优势:

  1. 精准区分加载方式:通过import和require字段,能明确指定两种模块规范各自的入口,不管是Node.js运行时还是现代打包工具,都能无歧义地识别。
  2. 优先级更高:当package.json存在exports字段时,Node.js会忽略main字段(除非exports中显式声明了默认入口),能避免旧字段带来的潜在冲突。
  3. 扩展性更强:可以轻松扩展配置更多场景的入口,比如TypeScript的类型声明文件入口、浏览器专属入口等,结构更清晰可控。

如果改用exports,你的配置可以调整为:

{
  "name": "@private-owner/tracking",
  "version": "0.0.1",
  "description": "Library which provides JS helper methods for GoogleAnalytics and DataWarehouse tracking",
  "main": "dist/tracking.cjs", // 兼容旧工具,可选保留
  "module": "dist/tracking.esm.js", // 兼容旧打包工具,可选保留
  "exports": {
    "import": "./dist/tracking.esm.js",
    "require": "./dist/tracking.cjs"
  },
  "repository": "https://github.com/@private-owner/tracking",
  "license": "UNLICENSED",
  "private": false,
  "type": "module"
}

保留main和module是为了兼容不支持exports的老旧工具,若只需要支持现代环境,也可以仅保留exports字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:30:28