Next.js构建/启动时无法读取API_SERVER环境变量求助
问题:执行build/start命令时API_SERVER未定义,但dev命令正常
执行npm run build或npm start时,抛出API_SERVER环境变量必须定义!的错误,但npm run dev可以正常读取.env里的变量。
错误截图:
相关文件内容
next.config.js
const { withPlugins, optional } = require('next-compose-plugins') // eslint-disable-next-line import/no-extraneous-dependencies const { PHASE_PRODUCTION_BUILD } = require('next-server/constants') const sass = require('@zeit/next-sass') const withCSS = require('@zeit/next-css') const { requireEnvVar } = require('./lib/nodeUtils') /** * 自定义Next.js配置 * @see https://nextjs.org/docs#custom-configuration */ const nextConfig = { /** * 运行时配置 * @see https://nextjs.org/docs#exposing-configuration-to-the-server--client-side */ publicRuntimeConfig: { // 在服务端和客户端均可访问 apiUrl: requireEnvVar('API_SERVER'), gtmId: requireEnvVar('GTM_ID'), }, /** * 禁用文件系统路由 * @see https://nextjs.org/docs#disabling-file-system-routing */ useFileSystemPublicRoutes: false, /** * 自定义webpack配置 * @see https://nextjs.org/docs#customizing-webpack-config */ webpack(config, { webpack }) { /** * 仅加载moment.js的特定语言包 * @see https://stackoverflow.com/a/25426019/956688 */ config.plugins.push( new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/) ) return config }, } /** * 使用next-compose-plugins加载多个插件 * @see https://github.com/cyrilwanner/next-compose-plugins */ module.exports = withPlugins( [ [sass], [withCSS], /** * 分析webpack打包结果 * @see https://github.com/zeit/next-plugins/tree/master/packages/next-bundle-analyzer * * 仅在生产构建阶段加载@zeit/next-bundle-analyzer可选插件 * @see https://github.com/cyrilwanner/next-compose-plugins#optional-plugins * @see https://github.com/cyrilwanner/next-compose-plugins#phases-array */ [ // eslint-disable-next-line global-require,import/no-extraneous-dependencies optional(() => require('@zeit/next-bundle-analyzer')), { analyzeServer: ['server', 'both'].includes(process.env.BUNDLE_ANALYZE), analyzeBrowser: ['browser', 'both'].includes( process.env.BUNDLE_ANALYZE ), bundleAnalyzerConfig: { server: { analyzerMode: 'static', reportFilename: '../../bundles/server.html', }, browser: { analyzerMode: 'static', reportFilename: '../bundles/client.html', }, }, }, [PHASE_PRODUCTION_BUILD], ], ], nextConfig )
.env
API_SERVER=http://localhost:3005 NEXTAUTH_URL=http://localhost:3000 GTM_ID=GTM-XXXXXXX
lib/nodeUtils.js
exports = module.exports = {} /** * 加载环境变量值,若未定义则抛出错误 * * @param {string} varName * @return {*} */ exports.requireEnvVar = function requireServerEnvVar(varName) { const envVar = process.env[varName] if (!envVar) { throw new Error(`${varName}环境变量必须定义!`) } return envVar }
package.json 脚本部分
"scripts": { "dev": "node server.js", "build": "next build", "clean": "rimraf ./.next ./node_modules/.cache", "start": "HTTPS=true cross-env NODE_ENV=production node server.js", "lint": "eslint --ext js,jsx --ignore-path .gitignore .", "lint-fix": "npm run lint -- --fix", "format-check": "prettier --check \"**/*.{js,jsx,json,css,scss,md}\"", "format-write": "prettier --write \"**/*.{js,jsx,json,css,scss,md}\"", "test": "echo \"Error: no test specified\" && exit 1", "analyze-both": "cross-env BUNDLE_ANALYZE=both next build", "analyze-browser": "cross-env BUNDLE_ANALYZE=browser next build", "analyze-server": "cross-env BUNDLE_ANALYZE=server next build" },
解决方案
原因
Next.js 默认仅在开发环境(dev)自动加载.env文件,生产构建/启动阶段不会自动读取该文件。你的dev命令正常是因为server.js可能已经手动加载了.env,但build命令直接执行next build,未加载环境变量,导致process.env.API_SERVER不存在,触发报错。
解决步骤
安装dotenv依赖
npm install dotenv --save在next.config.js顶部加载.env
在文件最开头添加代码,确保构建时先读取环境变量:require('dotenv').config()完善start命令(可选)
如果server.js未加载.env,要么在server.js顶部添加require('dotenv').config(),要么修改start脚本:"start": "HTTPS=true cross-env NODE_ENV=production node -r dotenv/config server.js"验证
重新执行npm run build和npm start,即可正常读取API_SERVER变量。
若
.env文件不在项目根目录,需给dotenv.config()传入路径参数,例如:require('dotenv').config({ path: './config/.env' })
内容的提问来源于stack exchange,提问作者Adesh Kumar
相关产品推荐
相关产品推荐

