在浏览器环境中使用 es modules 时,配置 package.json 的 browser 字段可以指定模块解析策略,从而让打包工具或环境自动选择正确的入口文件。具体做法是设置一个对象,将主入口映射到浏览器可用的版本(如经过转译的 esm 文件),并将特定平台或环境的条件映射到对应的构建产物,这样导入模块时就能获得兼容的代码。

如何区分 Node.js 和浏览器的入口文件?
通过为 main、module 和 exports 添加条件键值对来实现。Node.js 环境通常读取 main 或 exports 中的默认路径,而浏览器环境则优先读取标记为 browser 的路径。这种配置允许同一个包同时服务于服务端和客户端,无需分发多个包。

{
"name": "my-lib",
"version": "1.0.0",
"main": "./dist/node/index.cjs",
"module": "./dist/esm/index.mjs",
"browser": {
".": "./dist/browser/index.mjs"
},
"exports": {
".": {
"node": "./dist/node/index.cjs",
"default": "./dist/browser/index.mjs"
}
}
}
上述配置中,当 Node.js 运行时导入该包,会加载 CommonJS 格式的 index.cjs;而在浏览器中,无论使用哪种模块系统,都会加载 ESM 格式的 index.mjs。这确保了代码在不同环境下都能正确执行,避免了因语法不兼容导致的错误。
如何处理特定平台的依赖冲突?
当项目中存在针对特定平台优化的依赖时,可以通过 browser 字段进行重定向。例如,某些库提供了纯 JavaScript 版本和基于 C++ 绑定的高性能版本,浏览器环境无法运行 C++ 绑定,因此需要将其重定向到 JS 版本。这种机制不仅适用于主包,也适用于其子依赖,确保整个依赖树在目标环境中都能正常工作。

{
"name": "app",
"dependencies": {
"heavy-lib": "^2.0.0"
},
"browser": {
"heavy-lib": "heavy-lib/dist/browser-only.js",
"fs": false,
"path": false
}
}
在这个例子中,heavy-lib 被重定向到一个专门为浏览器构建的文件,而 fs 和 path 等 Node.js 内置模块被设置为 false,表示在浏览器环境中这些模块不可用。这种做法可以有效减少打包体积,并避免引入不必要的服务器端逻辑。
当 browser 字段与 exports 同时存在时,哪个优先级更高?
在现代打包工具和 Node.js 12+ 环境中,exports 字段的优先级高于 browser。如果 exports 中定义了条件映射,它将覆盖 browser 中的设置。这意味着开发者应该优先使用 exports 来定义多环境支持,因为它提供了更细粒度的控制能力,并且符合最新的模块化标准。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











