将 React-Express 应用程序部署到 Heroku 时遇到问题

时间:2021-01-16 23:57:59

标签: reactjs mongodb express mern

我正在尝试将一个 MERN 应用(使用 create react 应用构建)部署到 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)
    })
})

1 个答案:

答案 0 :(得分:1)

你有两个选择,

#1 - 使所有 url 相对,例如fetch('/api/all-reviews'),并使前端和后端运行在同一台服务器上。使用 build middleware 从后端提供静态构建文件(在运行 npm run build 后位于 express.static 文件夹中,假设您使用的是 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'));