exports字段必须是对象,键均以.开头,未显式声明的子路径一律被禁止访问,导入将报err_package_path_not_exported错误;支持条件导出如import/require/browser等细化行为,严禁写成字符串或数组。

要通过 package.json 的 exports 字段严格控制子路径暴露,核心是“显式声明 + 精确限制”:只列出你愿意公开的子路径,其余一律不可访问。Node.js 一旦发现 exports 字段,就会启用导出强制(Exports Enforcement),未声明的路径导入会直接报错 ERR_PACKAGE_PATH_NOT_EXPORTED。
必须以点开头的键名
exports 是一个对象,所有键必须以 . 开头,包括主入口和子路径:
-
"." : "./dist/index.js"—— 对应import "pkg"或require("pkg") -
"./utils" : "./src/utils.js"—— 允许import utils from "pkg/utils" -
"./constants" : "./src/constants.json"—— 允许读取 JSON 文件 -
"./package.json" : "./package.json"—— 必须显式加这一条,否则import pkg from "pkg/package.json"会失败
禁止隐式访问内部文件
不声明,就等于拒绝访问。例如:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 即使
dist/internal.js真实存在,没在exports中写"./internal": "./dist/internal.js",用户import "pkg/internal"就会报错 -
./src/、./test/、./scripts/这类目录默认完全屏蔽,无需额外操作 - 不要用通配符
"./lib/*": "./lib/*.js",除非你真想开放整个目录——这违背“严格控制”的初衷
用条件导出细化行为
同一子路径可按环境或模块类型返回不同文件,增强控制力:
"./feature": { "import": "./esm/feature.mjs", "require": "./cjs/feature.cjs" }"./browser-only": { "browser": "./dist/browser.js", "default": "./dist/node.js" }- 条件字段支持
import、require、browser、node、types等,现代工具链(Vite、Webpack 5+、TypeScript)均识别
避免常见配置错误
这些写法会导致加载失败或失去控制力:
- 把
exports写成字符串或数组,如"exports": "./index.js"—— 必须是对象 - 漏掉
"./package.json"声明,导致版本读取失败 - 路径使用反斜杠
"./utils\index.js"或大小写不一致(Linux/macOS 区分大小写) - 混用
main和exports却不保持语义一致,可能引发构建工具歧义










