代理子目录中 create-react-app 的 $PORT 值

Jos*_* K. 0 port heroku environment-variables create-react-app

我正在开发一个从节点端点提供 create-react-app 服务的存储库。因此,react 应用程序嵌套为子目录:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Procfile\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 frontend\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 README.md\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 build\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json <---- "proxy": "http://localhost:$PORT" \n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 public \n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 App.css\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 App.js\n\xe2\x94\x82   \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 // etc...\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 .env <----- frontend env file, removed PORT value from here\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 package.json\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.js\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 server.js\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 // etc...\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 .env <--- backend env file, PORT=9000 for node\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 static.json\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 yarn.lock\n
Run Code Online (Sandbox Code Playgroud)\n

从 .env 文件中删除端口值后,CRA 在端口 3000 上运行。如果我硬编码端口 9000 而不是 $PORT,则代理在开发中可以正常工作。

\n

但是,在部署到生产环境时,我希望前端代理 Heroku 的动态端口号,这是一个示例:\nHeroku 的可变端口号

\n

Heroku 似乎忽略了端口值,即使我故意在他们网站的 env 中定义它,值为 9000。

\n

我的问题是如何在前端定义代理而不让 CRA 在该端口号处实例,例如在前端 .env 中应用 PORT=9000 但在端口 3000 处加载 CRA。

\n

我尝试在脚本中定义端口号,同时确保我在前端环境中定义了 PORT=9000:

\n
  "scripts": {\n    "start": "export PORT=3000 && react-scripts start",\n
Run Code Online (Sandbox Code Playgroud)\n

CRA 将以 3000 加载,但我收到代理错误:\n无法代理错误

\n

小智 5

Heroku 不允许您选择端口,而是为您的应用程序分配一个端口以用作环境变量。在这里阅读更多内容

每个 Web 进程只是绑定到一个端口,并侦听来自该端口的请求。要绑定的端口由 Heroku 作为 PORT 环境变量分配。

  • 删除所有硬编码PORT变量

  • $PORT在您的文件中使用它并不理想,package.json因为您无法向其中添加逻辑。在您的 Nodejs 应用程序中读取端口变量,如下所示:

    const PORT = process.env.PORT || 3000
    
    Run Code Online (Sandbox Code Playgroud)

    这会将端口变量设置为环境变量中的任何内容PORT,如果未设置,则默认为 3000

  • 使用 CRA 为生产应用程序提供服务效率不高

  • 不要为react和nodejs运行两个服务器,而是使用nodejs应用程序来为生产构建的react应用程序提供服务

    const express = require('express')
    const path = require('path')
    const app = express()
    // All your other routes go here
    app.use('/', express.static(path.join(__dirname,'client/build'))) // this must be the last one
    
    Run Code Online (Sandbox Code Playgroud)

    注意:client/build这是假设您的反应应用程序是相对于您的项目根目录构建的

  • 代理设置只是为了开发方便,如果应用程序不是由 CRA 提供服务,则代理设置不起作用

  • 让 heroku 在构建时构建你的 React 应用程序:

    npm --prefix client run build # or if you use yarn
    yarn --cwd client build
    
    Run Code Online (Sandbox Code Playgroud)

    在你的外部package.json文件的构建脚本中

  • 您的启动脚本将运行您的nodejs服务器:

    "scripts": {
      "start": "node src/server.js",
      "build": "npm --prefix client run build"
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 不要将.env文件提交到heroku,如果您有heroku cli,请直接使用设置环境变量heroku config:set KEY=VALUE或使用仪表板设置

    注意:在推送代码之前执行此操作,以便在 React 应用程序的构建期间可以访问这些变量