Rollup打包的自定义SDK如何读取Next.js运行时环境变量
问题原因定位
出现这个问题基本是两个核心原因叠加:
- Next.js 本身对环境变量有暴露范围限制,不是所有
process.env下的变量都能在所有运行上下文拿到 - Rollup 打包你的自定义SDK时,默认可能把
process.env的引用静态替换/打了独立shim,导致SDK运行时根本访问不到Next.js项目的真实环境变量对象
可落地解决方案
按照优先级从高到低试:
1. 优先改SDK初始化逻辑,从根源规避打包替换问题
这是最稳妥、兼容性最好的方案,不用改Rollup配置也不用纠结Next.js版本差异
不要在SDK内部硬编码process.env.MY_VAR的读取逻辑,改成初始化时支持传入配置项:
// 你的SDK入口源码 export function createSDK(options = {}) { const runtimeVar = options.MY_VAR ?? process.env.MY_VAR // 后续SDK逻辑统一使用runtimeVar return { // sdk实例方法 } }
在Next.js项目中调用SDK时,主动把环境变量传入:
// Next.js项目中引入SDK的位置 import { createSDK } from 'your-custom-sdk' // 服务端/服务端组件中直接传 const sdk = createSDK({ MY_VAR: process.env.MY_VAR }) // 如果是客户端组件/客户端侧逻辑,使用带NEXT_PUBLIC_前缀的变量 const clientSideSdk = createSDK({ MY_VAR: process.env.NEXT_PUBLIC_MY_VAR })
2. 修正Rollup打包配置,保留process.env的运行时引用
如果不想改SDK的调用方式,就调整Rollup配置,避免打包时把process相关的引用替换掉:
- 移除
@rollup/plugin-replace中所有针对process.env.XXX的硬替换规则,不要在打SDK时就把环境变量值写死 - 如果用了
@rollup/plugin-node-resolve/@rollup/plugin-commonjs,关闭内置的process polyfill,避免打包时注入独立的空process对象// rollup.config.js 示例配置 import resolve from '@rollup/plugin-node-resolve' import commonjs from '@rollup/plugin-commonjs' import replace from '@rollup/plugin-replace' export default { input: 'src/index.js', output: { file: 'dist/index.js', format: 'esm', // 不要注入process shim globals: { process: 'process' } }, external: ['process'], // 把process标记为外部依赖,不要打进去 plugins: [ replace({ preventAssignment: true, // 不要写 'process.env.MY_VAR': 'xxx' 这类替换规则 }), resolve({ preferBuiltins: true, browser: false // 如果是同构SDK,根据目标运行环境调整,不要强制替换node内置模块 }), commonjs() ] } - 重新打包SDK发布到npm/本地link后再测试
3. 排查Next.js侧的环境变量配置问题
做完上面两步还读不到的话,检查Next.js本身的配置:
- 确认你的
.env/.env.production等环境变量文件放在Next.js项目根目录,不是放在SDK的目录里 - 客户端侧(浏览器运行的代码)默认只能读取带
NEXT_PUBLIC_前缀的环境变量,没有前缀的变量只会在服务端上下文暴露,不要在客户端代码里直接读没有前缀的变量 - 如果需要build后修改环境变量不重新打包生效,确保你读取变量的路由/组件是动态渲染的,不要在静态生成阶段把变量硬编码到产物里
- 先在和SDK同个运行上下文的业务代码里打印
process.env.MY_VAR,确认业务代码本身能读到值,再排查SDK的问题
内容的提问来源于stack exchange,提问作者NoowaH
相关产品推荐
相关产品推荐

