(MERN) 使用 Express.js 服务 React App 的正确方法是什么?

(MERN) What is the correct way to serve a React App using Express.js?

所以基本上我的问题是我主要只使用 node/express/mongoose 制作 API,并且从来没有为我的 React 应用程序提供服务,因为其他人总是在我们的 Plesk 中为我做这件事(我认为是通过 Apache。)

既然我终于在一边为客户端做一些 MERN 堆栈的事情,我想知道 'correct' 为已经构建的 React 应用程序提供服务的方式是什么。

Express 和 React-Router 冲突。我的意思是,如果我有一个 'About' 页面并且我转到 example.com/about express 如何知道这是我的单页 React 应用程序上的一个页面?只有一个 index.html 我页面上处理路由的任何其他内容都由 react-router 处理。

但是如果是文件或者文件夹呢?所以这是我的解决方案,既能提供网站的文件,又能访问网站的路由:

const apps = { //websites are put in this object and iterated through to make the code below less bloated.
        example: {
            folder: "example-website",
            app: express(),
            server: null,
            port: 80,
            protocol: "http", 
            cert: null,
            subdomains: []
        }
    }

    for(let website of Object.keys(apps)){ //Itterate through every website.
        website = apps[website]; //Make the website key the website object instead.

        const websitePath = path.join(__dirname+`/client/${website.folder}/build`); //Save path to website's build folder for ease of use.

        fs.readdir(websitePath, (err, files) => { //itterate through all files in the build folder
            if(err){ //log errors.
                console.log(err)
            } else { //continue if there wasn't an error.
                const fileArray = files.filter(file => file !== 'index.html')//remove 'index.html' from the array.

                website.app.use('/*', (req,res) =>{
                    let route = req.params["0"].substring(0, req.params["0"].indexOf('/')); //take the first part of the route.

                    if(fileArray.includes(route)){ //check if the first part of the route matches a file or folder.
                        res.sendFile(path.join(__dirname+`/client/${website.folder}/build/${req.params["0"]}`));
                    } else { //If the list of files doesn't include the route than the route is probably a route within the React App in React-Router
                        res.sendFile(path.join(__dirname+`/client/${website.folder}/build/index.html`));
                    }

                });

                //...more irrelevant code here.
            }

        })
    }

我想知道这是否是处理我的单页 React 应用程序对 react-router 的使用与 Express 处理路由的方式之间的冲突的正确方法。

我不太确定你是否对 API感到困惑, 我会解释一下,也许你可以更好地了解 MERN,

首先有2种:1是后端(API)2是前端(在本例中是Reactjs), 所以后端和前端,每个都有自己的业务,我相信你知道,所以 一旦 UI(本例中的前端是 Reactjs)需要数据,他们将通过 fetch(基本上)调用后端(API 在本例中是 Nodejs)来调用 api 并获取该数据出去 。

=> 所以你知道前端和后端是如何工作的,接下来:

Reactjs他们把很多元素分到一个组件去加载

  • 示例:google.com
  • 看:右上角有个header是一个组件,一个输入是另一个组件,另一个是另一个组件。

  • 它 运行 :当你搜索一些东西时, header 和输入没有加载,另一个组件是加载,所以当 url 改变时, react-router 将帮助您捕获在路由器中定义的 url 您可以阅读更多 here 关于 react-router .

==> 这意味着,当转到不同的 url 时,它们只会触发 url 使用的组件 localhost:3000/到localhost:3000/关于

如果你能详细说明这个问题,对其他人解释会更有帮助。

  1. 构建后端就像所谓的 'API calls' "building ways where you can make a request(send CRUD operations from client to database through server) and get a response (fetch data and deliver to a client)"。当然,您可以在后端操作数据等,但这几乎就是它的作用。 所以,假设你的后端文件夹有 Express.js,因为 Express 通过 app.use 设置路由,你很可能知道它的意思。 (*Express.js(后端)中的路由与 React 中的路由不同 - 例如,如果后端路由是您的应用程序和数据库之间的道路,那么 React 中的路由就像您的应用程序和数据库之间的道路客户)

  2. 前端就像一家商店,您可以把从数据库(您的仓库)中获取的数据(商品)呈现给客户(进行销售)。

现在,您需要使用 Axios 或 fetch() 等通过后端路由在您的前端中进行 API 调用。因为 "the way(routes) to the server is established in your back-end folder"。您的计算机中将有 2 个部分 运行(在开发阶段),一个是服务器(后端),另一个是您的网页(前端)。如果客户端导航到特定路由,将调用该组件,并且该组件具有方法(直接或间接)并进行 API 调用,并对数据执行某些操作。

我将link留给我最近的全栈React应用程序,你可以去检查结构以获得一些想法。

Check out my repo and structure here