如何借助环境变量实现package.json的条件导出配置
package.json 按环境区分exports导出路径实现方案
原生package.json的exports字段是静态声明配置,本身不支持直接写环境变量判断逻辑自动切换路径,以下是两种可落地的实现方案:
方案1:使用条件导出(推荐,全工具链兼容)
这是Node.js和主流构建工具原生支持的标准能力,不需要写额外脚本,配置完成后工具会自动根据当前环境匹配对应导出规则。
首先修改package.json的exports配置,注意高优先级的环境规则要放在通用规则前面:
"exports": { "development": { "import": "./src/a.es.js", "require": "./src/b.umd.js" }, "production": { "import": "./dist/a.es.js", "require": "./dist/b.umd.js" }, "import": "./dist/a.es.js", "require": "./dist/b.umd.js" }
不同环境的匹配规则不需要额外写逻辑判断,工具会自动处理:
- Node.js运行时:开发环境启动时添加
--conditions development参数即可匹配源码路径,例:node --conditions development dev-server.js;生产环境不加该参数会自动 fallback 到dist目录的构建产物 - Vite/Rollup:开发模式默认优先匹配
development条件,生产构建自动匹配production条件,零额外配置 - Webpack 5+:会根据配置的
mode值自动匹配对应条件,mode: 'development'走源码分支,mode: 'production'走构建产物分支
方案2:脚本动态修改exports配置(仅适合本地项目使用)
如果需要更灵活的自定义判断逻辑,可以写简单脚本在执行命令前动态改写package.json的exports字段。
- 项目根目录新建
resolve-exports.cjs脚本:
const fs = require('fs'); const path = require('path'); const pkgPath = path.resolve(__dirname, 'package.json'); const pkg = require(pkgPath); pkg.exports = process.env.NODE_ENV === 'development' ? { import: './src/a.es.js', require: './src/b.umd.js' } : { import: './dist/a.es.js', require: './dist/b.umd.js' }; fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
- 在
package.json的脚本命令里添加执行钩子:
"scripts": { "predev": "NODE_ENV=development node resolve-exports.cjs", "prebuild": "NODE_ENV=production node resolve-exports.cjs" }
这个方案的缺点是会直接修改本地package.json文件,容易把动态修改后的配置误提交到代码仓库,需要额外加git忽略或者配置执行后还原逻辑。如果你的包需要发布到npm供外部使用,禁止用这个方案,否则会导致发布的包配置错误。
注意:条件导出的匹配顺序是从上到下优先级递减,一定要把环境相关的规则放在通用的
import/require规则前面,否则会被提前匹配到通用规则,环境配置不生效。
内容的提问来源于stack exchange,提问作者teteyi3241
相关产品推荐
相关产品推荐

