You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 14项目分支环境变量匹配异常问题修复请求

问题:Next.js 14 部署时环境文件加载错误

我们的项目基于Next.js 14,使用yarn包管理器,有development和main两个核心分支,对应.env.development与.env.production环境配置文件。目前CI/CD流水线可正常执行,项目也能启动,但在development分支部署时,系统仍加载.env.production而非指定的.env.development。我们已尝试根据分支动态复制.env文件,但问题依旧。


相关配置文件

CI/CD 配置文件

stages:
  - build

build:
  stage: build
  tags:
    - backend-blinkship
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t <--CONTAINER_NAME--> --build-arg branch=${CI_COMMIT_BRANCH} .
    - DOCKER_TAG=$CI_REGISTRY/customer-portal/frontend/CONTAINER_NAME:$PROJECT_VERSION
    - docker push <--CONTAINER_NAME-->

Dockerfile

FROM node:20.9.0-alpine as base
WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY . /app
ARG branch
RUN if [ "$branch" = "main" ] || [ "$branch" = "master" ]; \
    then cp .env.production /app/.env; \
    else cp .env.development /app/.env; \
    fi
RUN yarn install
RUN yarn build
CMD ["yarn", "start"]
EXPOSE 3000

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {};

const { parsed: localEnv } = require('dotenv').config({
  path: process.env.NODE_ENV === 'production' ? '.env.production' : '.env.development',
});

module.exports = {
  env: {
  },
};

package.json

{
  "name": "blink-ship-front-end",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint --ext .ts,.tsx .",
    "prepare": "husky",
    "format": "prettier-eslint --write $PWD/'**/*.{ts,tsx}'",
    "check-lint": "eslint . --ext ts --ext tsx --ext js",
    "check-types": "tsc --pretty --noEmit",
    "test-all": "npm run check-format && npm run check-lint && npm run check-types && npm run build"
  },
  "dependencies": {
    "@ant-design/icons": "^5.3.0",
    "antd": "^5.13.1",
    "antd-img-crop": "^4.21.0",
    "axios": "^1.6.5",
    "classnames": "^2.5.1",
    "dotenv": "^16.4.5",
    "eslint-config-prettier": "^9.1.0",
    "js-cookie": "^3.0.5",
    "moment": "^2.30.1",
    "next": "^14.2.2",
    "next-auth": "^4.24.5",
    "nextjs-toploader": "^1.6.11",
    "nprogress": "^0.2.0",
    "react": "^18",
    "react-dom": "^18",
    "swr": "^2.2.5",
    "tailwindcss": "^3.4.1",
    "xlsx": "^0.18.5"
  },
  "devDependencies": {
    "@types/js-cookie": "^3.0.6",
    "@types/node": "^20",
    "@types/nprogress": "^0.2.3",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "@typescript-eslint/eslint-plugin": "^6.0.0",
    "@typescript-eslint/parser": "^6.0.0",
    "autoprefixer": "^10.0.1",
    "eslint": "^8",
    "eslint-config-airbnb-typescript": "^17.1.0",
    "eslint-config-next": "14.0.4",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-jsx-a11y": "^6.8.0",
    "eslint-plugin-prettier": "^5.1.3",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "husky": "^9.0.11",
    "postcss": "^8",
    "prettier": "^3.2.4",
    "typescript": "^5"
  }
}

相关截图

截图1
截图2


问题分析与修复方案

核心问题

  1. Next.js 构建默认行为:next build 会自动将NODE_ENV设为production,不管当前分支是什么。你在next.config.js里通过NODE_ENV判断加载的.env文件,会一直指向.env.production,覆盖了Dockerfile复制的文件。
  2. next.config.js配置无效:你导入了localEnv但未将其注入到Next.js环境变量中,等于没有生效。

修复步骤

1. 修正 next.config.js

去掉手动加载dotenv的逻辑,改用Next.js内置的环境变量机制,同时确保环境变量能被正确注入:

/** @type {import('next').NextConfig} */
const nextConfig = {
  env: process.env, // 将系统环境变量注入到Next.js
};

module.exports = nextConfig;

2. 调整 Dockerfile,明确设置环境变量

在复制.env文件后,持久化对应的NODE_ENV,避免Next.js构建时自动覆盖:

FROM node:20.9.0-alpine as base
WORKDIR /app
RUN apk add --no-cache libc6-compat
COPY . /app
ARG branch

# 根据分支复制对应.env文件并设置NODE_ENV
RUN if [ "$branch" = "main" ] || [ "$branch" = "master" ]; \
    then cp .env.production /app/.env && echo "NODE_ENV=production" >> /app/.env; \
    else cp .env.development /app/.env && echo "NODE_ENV=development" >> /app/.env; \
    fi

RUN yarn install
RUN yarn build
CMD ["yarn", "start"]
EXPOSE 3000

3. (可选)优化CI/CD脚本,直接传递环境变量

在CI/CD中提前判断分支并传递NODE_ENV参数,让逻辑更清晰:

script:
  - export TARGET_ENV=$([ "$CI_COMMIT_BRANCH" = "main" ] || [ "$CI_COMMIT_BRANCH" = "master" ] && echo "production" || echo "development")
  - docker build -t <--CONTAINER_NAME--> --build-arg branch=${CI_COMMIT_BRANCH} --build-arg target_env=${TARGET_ENV} .

然后Dockerfile中接收参数:

ARG target_env
ENV NODE_ENV=${target_env}

ARG branch
RUN if [ "$branch" = "main" ] || [ "$branch" = "master" ]; \
    then cp .env.production /app/.env; \
    else cp .env.development /app/.env; \
    fi

4. 验证配置

在Dockerfile的yarn build前添加打印步骤,确认环境变量是否正确:

RUN cat /app/.env && echo "当前NODE_ENV: $NODE_ENV"

额外提示

Next.js 14中,客户端组件需要访问的环境变量必须加上NEXT_PUBLIC_前缀,否则无法在前端代码中读取。如果你的.env文件包含客户端需要的变量,记得添加该前缀。

内容的提问来源于stack exchange,提问作者elahe karami

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 01:27:32