package.json 中的 entry point 字段
在 package.json
中,定义模块的入口点 (entry point
) 字段是及其重要的
package.json 代码示例
jsonc
{
"name": "icebreaker-npm-basic-package",
"version": "1.0.0",
"type": "module",
"main": "./index.cjs", // CommonJS 主入口(用于 Node require)
"module": "./index.mjs", // 非标准,但很多构建工具支持(ESM)
"types": "./index.d.ts", // TypeScript 类型定义
"exports": {
".": {
"types": "./index.d.ts", // TypeScript 类型定义
"require": "./index.cjs", // Node require 使用 CommonJS
"import": "./index.mjs" // Node import 使用 ESM
}
}
}
📝 字段说明:
字段 | 说明 |
---|---|
"type": "module" | 默认将 .js 文件视为 ESM |
"main" | Node 中 require('pkg') 会使用 CommonJS 文件 |
"module" | 给打包工具提供 ESM 入口,非标准,但有用 |
"exports" | 更现代且明确的方式,指明模块格式,兼容 Node >=12 |
"types" | 给 TypeScript 指明类型定义文件的位置 |
官方文档: package-entry-points
为什么说 module 是非标准的?
在 package.json
中,"module"
字段是一个 非标准的字段,但在现代前端工具(如 Webpack、Rollup、Vite 等)中被广泛使用,用于指向 ES Module 格式的入口文件,以便这些工具能够做更好的静态分析与 tree-shaking。
下面是不同工具/环境下可能会读取 "module"
字段的情况:
✅ 什么情况下会加载 "module"
字段?
打包工具(Webpack、Rollup、Vite、Snowpack, Parcel 等)
- 当你使用这些工具打包代码时,它们会优先尝试读取:
"exports"
字段(如果存在,优先于其他字段)"module"
字段(通常表示 ESM 格式)"main"
字段(通常表示 CommonJS 格式)
示例:
js
// 在 Webpack 中引入某个 npm 包时,如果该包的 package.json 有 module 字段
// Webpack 会优先使用这个字段所指向的 ESM 文件
import foo from 'icebreaker-npm-basic-package'
Vite、Snowpack, Parcel
这些工具天生以 ESM 为主,会优先读取"module"
字段。
🚫 不会加载 "module"
字段的情况
Node.js 本身
- Node.js 并不识别
"module"
字段,加载模块时它依赖的是:"type"
字段(决定是否为 ESM 模式)"main"
字段(默认入口)- 或者直接通过
"exports"
字段(推荐现代做法)
例如,在你的 package.json
中:
json
{
"type": "module",
"main": "index.cjs",
"module": "index.js"
}
- 你运行
node .
时,Node 会根据"main"
加载index.cjs
- 如果你运行
node index.js
,它会根据文件扩展名和"type": "module"
以 ESM 模式运行,但并不会自动从"module"
字段寻找入口
推荐现代做法(如要兼容多种环境):
可以使用 exports
字段更明确地配置入口文件:
jsonc
{
"exports": {
".": {
"types": "./index.d.ts",
"require": "./index.cjs",
"import": "./index.js"
},
"./xxx": {
"types": "./xxx.d.ts",
"require": "./xxx.cjs",
"import": "./xxx.js"
}
}
}
这样,Node.js 和打包工具都能正确识别和区分 ESM 和 CommonJS。
总结:
环境/工具 | 是否使用 "module" 字段 | 说明 |
---|---|---|
Node.js | ❌ 不会使用 | 使用 "main" 或 "exports" |
Webpack/Rollup | ✅ 会使用 | 优先用来加载 ESM 版本 |
Vite/Snowpack | ✅ 会使用 | 用于选择 ESM 格式 |
TypeScript | ❌ 不直接使用 | 会用 "types" 字段找类型声明 |