【问题标题】:Having trouble deploying React-Express app to Heroku将 React-Express 应用程序部署到 Heroku 时遇到问题
【发布时间】:2021-04-21 15:44:25
【问题描述】:

我正在尝试将 MERN 应用(使用 create react app 构建)部署到 Heroku,但每当我尝试访问应用 URL 时,它都会返回 404 错误。

我检查了 Heroku 错误日志,它返回了以下错误:

app[web.1]: ls: cannot access '/app/build/static/js/*.js': No such file or directory
Error injecting runtime env: bundle not found '/app/build/static/js/*.js'. See: https://github.com/mars/create-react-app-buildpack/blob/master/README.md#user-content-custom-bundle-location


我已经构建了我的项目,使其在两个不同的服务器上运行:客户端在 localhost:3000 上,它代理在 localhost:5000 上表达的请求。

我已经运行 npm run build,设置了静态中间件,并尝试正确配置我的 api 调用/路由,但它仍然无法正常工作。关于为什么以及如何解决它的任何建议?详情如下:

项目结构

+client
   |
   +-build
      +-static
        +-css
        +-js
        +-media
   +-node_modules
   +-public
   +-src
     |
     +-components
        +-App.js
        +-index.js
//server
+-models
+-node-modules
+-package-lock.json
+-package.json
+-server.js

代理(在 package.json 中):
"proxy": "http://localhost:5000"

Heroku 构建脚本(在 client/package.json 中):

  "scripts": {
    "start": "react-scripts start",
    "heroku-postbuild": "cd client && npm install --only=dev && npm install && npm run build",

服务器配置:

const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Listening on port ${port}`));


//Middleware
app.use(express.static(path.join(__dirname, 'client/build')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.urlencoded())
app.use(cors())

app.get('*', (req,res) =>{
    res.sendFile(path.join(__dirname+'/client/build/index.html'));
});

以下是我构建 API 的方式。注意:我已经从我的 axios 请求的 URL 中删除了 'localhost:5000':

来自 React 组件的 API 调用:

    useEffect(() => {
    axios.get('/api/all-reviews')
    .then(review => {
        setReviews(review.data)
    })
    .catch(err => {
        console.log(err)
    })
},[])

对应的特快路线

app.get('/api/all-reviews', (req,res) => {
    Review.find()
    .then((result) => {
        res.send(result)
    })
    .catch(err => {
        console.log(err)
    })
})

【问题讨论】:

  • 您的前端和后端是在同一台服务器上运行还是在不同的服务器上运行? (即您的后端是否将您的前端作为静态文件提供服务?)
  • 它们在不同的服务器上运行:客户端在端口 3000 上,然后服务器端在 5000 上。我已经设置了我的项目,以便所有客户端请求都代理到端口 5000 上的服务器,不过。

标签: reactjs mongodb express mern


【解决方案1】:

你有两个选择,

#1 - 使所有 url 相对,例如fetch('/api/all-reviews'),并且前端和后端都在同一台服务器上运行。使用express.static middleware 从您的后端提供静态构建文件(在运行npm run build 后在build 文件夹中找到,假设您正在使用create-react-app)。 请注意,您可以在生产中执行此操作,同时在开发中仍依赖使用 process.env.NODE_ENV 的代理。一个示例实现是

// put this at the end of your server.js file

if (process.env.NODE_ENV === 'production') {
    app.use(express.static(path.join(__dirname, '../client/build')));
}

#2 - 在不同的服务器上运行后端和前端,并根据代码是在开发还是生产中运行来调整路径 举个例子:

const prefix = process.env.NODE_ENV === 'production' ? "http://heroku_app_address" : "http://localhost:5000"
function getUrl(relativeUrl) {
   return prefix + "/" + relativeUrl;
}

fetch(getUrl('api/all-reviews'));

【讨论】:

  • 感谢您的回答。不过我想知道,getUrl 函数应该在我的项目中的哪个位置?我的src 文件夹中有一个名为helperFunctions 的文件,我暂时将其放在其中,并将其导出到我需要的组件中。一旦导入到特定组件中,我可以这样使用它吗? axios.get(getUrl(api/all-reviews))。最后一个问题,我是否需要设置一个 .env 文件?干杯
  • helperFunctions 听起来是个不错的地方。如果您使用流行的 npm 模块 dotenv - 将您的自定义环境变量从 .env 文件加载到 process.env 中,则需要一个 .env 文件。否则,您不需要这样的文件。在heroku中,您可以使用heroku config:set VAR_NAME=value 设置环境变量
猜你喜欢
  • 1970-01-01
  • 2016-08-27
  • 2017-05-03
  • 1970-01-01
  • 2021-11-08
  • 2019-02-18
  • 2011-08-30
  • 1970-01-01
相关资源
最近更新 更多