条件导出是Node.js 12.20+引入的package.json exports字段机制,通过声明多组环境条件(如"import"、"node"、"browser"、"bun")匹配对应入口文件,由运行时或构建工具在模块解析阶段动态选择,无需修改源码即可适配不同环境。

条件导出(Conditional Exports)是 Node.js 12.20+(推荐 14.13+)引入的 package.json 字段,用于在不修改源码的前提下,让同一包对不同运行时(如 Node.js、Bun、浏览器)自动提供适配的入口文件。它不是“编译时切流”,而是模块解析阶段由运行时或打包工具(如 Vite、Webpack、esbuild)依据环境条件匹配并加载对应模块。
核心机制:依赖 package.json 的 exports 字段
通过 "exports" 对象声明多组导出规则,每条规则包含一个条件键(如 "import"、"require"、"node"、"browser"、"bun")和对应模块路径。运行时/工具按优先级顺序匹配第一个满足条件的入口。
典型结构示例:
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"bun": "./dist/index.bun.js",
"node": "./dist/index.node.js",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"browser": "./dist/index.browser.js",
"default": "./dist/index.mjs"
}
}
}
注意:"bun" 是 Bun 1.0+ 原生支持的条件(无需插件),"browser" 被现代打包工具广泛识别,"node" 和 "default" 用于兜底。
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
运行时行为差异与匹配逻辑
不同环境触发不同条件组合,实际加载取决于运行时自身策略或构建工具配置:
-
Node.js(ESM 模式):匹配
"import"→"node"→"default" -
Node.js(CommonJS 模式):匹配
"require"→"node"→"default" -
Bun(ESM 或 CJS):优先匹配
"bun";未定义则回落到"import"/"require"+"node" -
浏览器(原生 ESM):匹配
"import"→"browser"→"default" -
Vite / Webpack / esbuild 构建时:默认识别
"browser"、"import"、"require";Vite 还支持"development"/"production"等环境条件
实践要点:构建与发布准备
条件导出本身不生成代码,需配合构建流程产出多份目标文件:
- 用 TypeScript 或 esbuild 分别构建
.mjs(ESM)、.cjs(CJS)、.browser.js(含 DOM API 替换)、.bun.js(可启用 Bun 特有 API,如Bun.file()) - 确保
package.json中"type": "module"与导出格式一致;若同时支持 CJS,建议设为"module"并显式声明"require" - 避免循环条件:例如不要同时写
"browser"和"node"指向同一文件却依赖互斥 API,否则运行时报错 - 测试验证:分别用
node -e "import('your-pkg')"、bun run -e "import('your-pkg')"、import到 HTML 中,确认加载路径正确
常见陷阱与绕过方案
并非所有场景都开箱即用:
- 旧版 Node(:回退到
"main"/"module"字段,或使用"exports"+"exports: false"兜底 -
某些 bundler 忽略 "bun" 条件:Bun 自身能识别,但 Webpack 默认不认;此时可在构建配置中添加自定义条件(如 Webpack 的
resolve.conditionNames) -
类型声明未对齐:用
"types"指向统一 d.ts,或为不同入口提供declare module 'pkg/browser'等路径映射 -
动态
require()或import()字符串无法被静态分析:条件导出只作用于静态导入;动态路径需手动判断typeof window !== 'undefined'等运行时特征

















