修改Create React App默认端口:环境变量启动脚本调用异常求助
我来帮你理清这里的问题所在,以及对应的解决方案:
为什么process.env.REACT_APP_PORT在scripts里无效?
package.json里的scripts命令是在**系统shell(比如bash/zsh或者Windows的CMD/PowerShell)**中执行的,而process.env是Node.js环境里的变量读取方式——shell根本不认识这个语法!当你写process.env.REACT_APP_PORT react-scripts start时,shell会把process.env.REACT_APP_PORT当成一个要执行的命令,自然找不到这个命令,就会返回undefined报错。
而你之前用PORT=4000 react-scripts start能生效,是因为这是shell的环境变量赋值语法:在执行react-scripts start之前,先给当前shell会话的PORT变量设置值,react-scripts启动时会读取这个shell环境中的PORT变量来确定服务端口。
另外要区分:你在index.js里能读到REACT_APP_PORT,是因为react-scripts会自动加载.env.development文件,把所有REACT_APP_开头的变量注入到客户端代码中,但这和服务启动时读取的shell环境变量是完全独立的两个环节。
解决方案
这里给你几个可行的方案,按需选择:
方案1:用dotenv-cli在shell中读取.env变量(类Unix系统:Mac/Linux)
首先安装dotenv-cli工具,它能帮我们在shell中读取.env文件里的变量:
npm install dotenv-cli --save-dev
然后修改package.json的start脚本:
"start": "PORT=$(dotenv -e .env.development get REACT_APP_PORT) react-scripts start"
这样dotenv-cli会读取.env.development里的REACT_APP_PORT值,赋值给shell的PORT变量,再启动react-scripts。
方案2:跨平台兼容方案(支持Windows/Mac/Linux)
如果需要兼容Windows系统,搭配cross-env来统一环境变量设置方式:
先安装依赖:
npm install cross-env dotenv-cli --save-dev
然后修改scripts:
"start": "cross-env PORT=$(dotenv -e .env.development get REACT_APP_PORT) react-scripts start"
方案3:用Node.js脚本中转(最灵活)
写一个简单的Node.js脚本,读取.env变量后再启动react-scripts,这样不管什么平台都能兼容:
- 先安装dotenv(如果还没装):
npm install dotenv --save-dev
- 在项目根目录创建
start-server.js文件:
const { spawn } = require('child_process'); // 加载development环境变量 require('dotenv').config({ path: '.env.development' }); // 设置PORT变量, fallback到默认的3000 process.env.PORT = process.env.REACT_APP_PORT || 3000; // 启动react-scripts start,继承当前终端的输入输出 spawn('react-scripts', ['start'], { stdio: 'inherit' });
- 修改package.json的start脚本:
"start": "node start-server.js"
这样Node.js会先读取.env.development里的变量,设置到进程环境中,再启动react-scripts,完美解决问题。
内容的提问来源于stack exchange,提问作者Brian Harrison

