Node.js生产服务器环境变量返回undefined问题求助
碰到这种生产环境变量加载失败的问题确实挺闹心的,我之前部署Node项目时也踩过类似的坑,给你整理几个排查和解决的方向,应该能帮你搞定:
确认dotenv的加载路径和时机
生产服务器上pm2启动项目时的工作目录(cwd)可能和你预期的项目根目录不一致,导致dotenv找不到.env文件。你可以尝试指定.env的绝对路径来加载:const path = require('path'); require('dotenv').config({ path: path.join(__dirname, '../.env') });或者直接写死绝对路径(比如
/var/www/your-project/.env),这样能避免工作目录的影响。另外,确保这条加载语句放在你所有使用环境变量的代码之前,比如在www文件的最顶部。优化pm2的启动配置
依赖dotenv有时候会受启动顺序影响,不如直接在pm2的配置文件里指定环境变量更可靠。你可以创建一个ecosystem.config.js文件:module.exports = { apps: [{ name: 'your-app-name', script: './www', cwd: '/path/to/your/project/root', // 明确指定项目根目录 env_file: '/path/to/your/project/root/.env', // 直接让pm2加载.env文件 env: { NODE_ENV: 'production' } }] };之后用
pm2 start ecosystem.config.js重启项目,这样pm2会自动帮你加载.env里的变量,不用再依赖dotenv的加载逻辑。检查.env文件的格式和内容
别忽略了最基础的点:生产服务器上的.env文件有没有语法错误?比如变量名前后多了空格、值里有空格但没加引号、或者变量名写错了(和本地的.env对比一下)。正确的格式示例:DB_CONNECTION=mysql://user:pass@localhost:3306/db API_SECRET="this is a secret with spaces"验证node和dotenv的版本兼容性
本地和生产服务器的node版本、dotenv版本不一致也可能导致加载失败。分别在本地和生产运行以下命令对比:node -v npm list dotenv如果版本差异大,建议把生产环境的版本统一成和本地一致的。
加调试代码定位问题
你可以在代码最顶部加一段调试日志,看看工作目录和环境变量的加载情况:console.log('当前工作目录:', process.cwd()); console.log('加载前的变量:', process.env.YOUR_VARIABLE); // 换成你要测试的变量名 const path = require('path'); require('dotenv').config({ path: path.join(__dirname, '../.env') }); console.log('加载后的变量:', process.env.YOUR_VARIABLE);然后用
pm2 restart your-app重启,再看日志pm2 logs your-app,这样能明确是找不到.env文件,还是加载后变量依然不存在。关于import改require的问题
如果你之前尝试把require改成import后没响应,大概率是因为你的项目没配置ES模块。如果要使用import,需要在package.json里添加"type": "module",然后dotenv的加载代码要写成:import dotenv from 'dotenv'; import path from 'path'; dotenv.config({ path: path.join(import.meta.dirname, '../.env') });不过生产环境用CommonJS(require)其实更稳妥,除非你明确需要ES模块的特性。
备注:内容来源于stack exchange,提问作者Smith

