ExpressJS 由 ejs 和 React 前端混合支持

ExpressJS backed with mix of ejs and React frontend

我目前有一个带有 Express 后端的 NodeJS 应用程序,所有前端都是用 EJS 实现的。当前的示例路线如下所示:

router.get("/:name&:term", function(req, res) {
    Course.find({ courseName: req.params.name, courseTerm: req.params.term }).populate("students")
    .exec(function(err, foundCourse) {
        if (err) {
            console.log(err);
        } else {
            console.log(foundCourse)
            res.render("courses/show", { course: foundCourse });        
        }
    });
});

我已经按照上面的示例路线实现了网站的很多页面。所以结构看起来像:

localhost:3000
-/courses
   -/show
   -/review
-/professors
   -/show
   -/rating
...

但我最近参加了 React 课程,想将 React 用于新页面,例如 localhost:3000/groups

有没有一种方法可以对某些页面使用 React,并且仍然有我目前拥有的 EJS 页面?还是我必须将所有 EJS 页面重写为 React 组件?我对网络开发还是很陌生,所以任何建议都将不胜感激。

根据我的理解,我必须让 React 应用只捕获某些 requests/routes 但我不太确定该怎么做。

当使用 SSR(服务器端渲染)时,Reactjs 组件可以成为后端代码的一部分,这要复杂得多。或者您可以使用 express 静态服务器来为准备部署的 reactjs 应用程序提供服务,那么 express 将只是一个简单的静态文件路由器。

要彻底回答这个问题我得写一本小书,所以我只展示一个基本的代码渲染案例client-side。我还假设您知道如何将 jsx 转换为 js,所以我将所有反应文件视为已经转换(即所有 <> 都转换为 React.createElement())。

首先,您必须创建一个将由 React 处理的路由 (/groups),(我假设您将像示例中那样使用一些数据进行渲染):

router.get("groups/:name&:term", function(req, res) {
    Groups.find({ groupName: req.params.name, courseTerm: req.params.term }).populate("students")
    .exec(function(err, foundGroup) {
        if (err) {
            console.log(err);
        } else {
            // here will be the react rendering code        
        }
    });
});

假设您在index.js中有react代码,您必须将其添加到html代码以及应用程序所需的数据中:

router.get("groups/:name&:term", function(req, res) {
    Groups.find({ groupName: req.params.name, courseTerm: req.params.term }).populate("students")
    .exec(function(err, foundGroup) {
        if (err) {
            console.log(err);
        } else {
            res.send(`<html>
               <head>
                 <script>
                   const initialData=${JSON.stringify(foundGroup)};
                 </script>
               </head>
               <body>
                 <div id="react-root"></div>
                 <script src="index.js"></script>
               </body>
            </html>`);
                    
        }
    });
});

您的 App 应该像这样使用数据:

React.render(<App initialData={initialData}/>, document.getElementById("react-root");

这应该让你的反应代码启动 运行。更进一步,您可以使用 react-dom/server 在服务器上预呈现 html,并使用 mix-in ejs 文件作为模板,您可以在其中注入反应代码以利用现有的代码库。

Is there a way to use React for some pages and still have EJS pages that I currently have?

是的,你可以,React 只是 javascript。

您可以将 create-react-app 用于单个页面并从您选择的路径提供该页面,但请记住,您的 front-end 不会通过这样做成为 SPA,您只会在特定路线上提供 React 应用程序。

更好的方法是不使用 create-react-app 而是设置您的自定义 webpack 构建过程以将 jsx 转换为 javascript,编写一个最小的 ejs 模板以包含您的转译 javascript 代码到 HTML,并从路由提供该模板。