【问题标题】:React-router URL's, Routing node/express & file structureReact-router URL,路由节点/快递和文件结构
【发布时间】:2020-12-23 02:59:06
【问题描述】:

文件结构

.root
|-client
| -build
| -node_modules
| -public
| -src
|  -components
|  -resources
|   -data
|   -images
|   -templates
|-server
| -models
| -public
| -routes
| -server.js

server.js

//Required NPM Packages
const express                =         require('express'),
      app                    =         express(),
      cors                   =         require('cors'),
      bodyParser             =         require('body-parser'),
      mongoose               =         require('mongoose'),
      methodOverride         =         require('method-override');

//MongoDB models.
const Product                =         require('./models/Product');

//Routes.
const indexRoute             =         require('./routes/index');
const demoRoute              =         require('./routes/demo');
const bootstrapTemplateRoute =         require('./routes/bootstrapTemplate');

//Port.
const _PORT = process.env.PORT || 5000;

//Connect to mongoDB.
mongoose.connect({pathToMongoDB}, {useNewUrlParser:true, useUnifiedTopology:true});

//Setup body-parser.
app.use(bodyParser.urlencoded({extended:true}));

//Allow express/node to accept Cross-origin resource sharing.
app.use(cors());

//Set view engine to EJS.
app.set('view engine', 'ejs');

//Change views to specified directory
app.set('views', path.join(__dirname, '..', 'client','src','Resources','templates'));


app.use(express.static(__dirname+"/public"))
app.use(express.static("client/build"));
app.use(express.static("client/Resources/templates"));


//Setup method override.
app.use(methodOverride("_method"));

//register routes to express.
app.use('/', indexRoute);
app.use('/demo', demoRoute);
app.use('/bootstrapTemplate', bootstrapTemplateRoute)

//listen to established port.
app.listen(_PORT, () => {
    console.log(`The server has started on port ${_PORT}!`);
});


module.exports = app;

问题

当我单击后退按钮或在浏览器栏中加载页面时,nodeJS 声明它无法获取该页面。我认识到前端和后端请求是不同的,因为 React-Router 通过它自己的 JavaScript 处理路由,允许零页面重新加载,但是你如何真正解决 nodeJS/Express 上的问题?

此外,当我转到 localhost:3000/demo 时,它会从我的 mongoDB 返回数据并以 json 格式呈现,而不是加载正确的页面。

目前正在使用以下 Nginx 基本路由配置开发 MERN 堆栈。

http{

    server{
        listen 3000;
        root pathToRoot/client/build;

        location / {
            proxy_pass http://localhost:5000/;
        }
            
    }
}

events {

}

我相信问题出在我通过 express/nodejs 的路由中。我无法创建明确的特定路线并呈现正确的页面,因为 react 正在为我呈现它。我看了以下问题React-router urls don't work when refreshing or writing manually。我应该做一个全面的并重新路由回主索引页面吗?这似乎会使书签无法使用。

编辑

这是 2 个节点路由。

index.js

const express                = require('express'),
      router                 = express.Router();


router.get("/", (req,res) => {
    //Render index page.
    res.render("index");
});

演示.js

 const express = require('express'),
      router = express.Router();

const Product = require('../models/Product');


router.get('/:searchInput', (req,res) => {
      Product.find({ $text: {$search: req.params.searchInput}}, (err,foundItem) => {
            if(err){
                  console.log(err);
            }else{
                  res.send(foundItem);
            }            
      })
})

router.get('/', (req, res) => {     
      Product.find({}, (err, foundItem) => {
            res.send(foundItem);
      });
});


module.exports = router;

【问题讨论】:

  • Does this work for you?我认为问题在于您只为/ 路由提供index.html 文件,但您想为所有路由提供它。
  • 我添加了我目前拥有的两条路线的编辑。我目前只在我们登陆页面时提供 index.html 文件。虽然我很困惑,因为 React 会渲染所有前端页面,所以我需要渲染多个页面。当我路由到演示页面时,会调用 mongo 并取回数据。根据 React useEffect/useState
  • 我可能会走得更远,但通常服务器设置为返回 index.html 而不是 404 页面。这样,您可以向服务器询问任何 ol' 路由,如果它不知道,它会返回 React 页面,然后 React-Router DOM 会计算出来。

标签: javascript node.js reactjs express


【解决方案1】:

我会尝试将您的开发文件夹与构建文件夹分开,因为一旦您开始运行react build,它可能会变得有点混乱。我使用的结构是:

api  build  frontend  run_build.sh

api 文件夹包含我对 express 服务器的开发,frontend 包含我对 react 的开发,build 是从 run_build.sh 脚本创建的,看起来像这样。

#!/bin/bash
rm -rf build/

# Build the front end
cd frontend
npm run build

# Copy the API files
cd ..
rsync -av --progress api/ build/ --exclude node_modules

# Copy the front end build code
cp -a frontend/build/. build/client/

# Install dependencies
cd build
npm install

# Start the server
npm start

现在在您的build 目录中,您应该有子文件夹client,其中包含您的反应代码的构建版本,没有任何混乱。要告诉 express 使用某些路由进行反应,请在 express server.js 文件中添加以下内容。

注意在添加 react 路由之前先添加你的 express api 路由,否则它将不起作用。

// API Routing files - Located in the routes directory // 
var indexRouter         = require('./routes/index')
var usersRouter         = require('./routes/users');
var oAuthRouter         = require('./routes/oauth');
var loginVerification   = require('./routes/login_verification')

// API Routes //
app.use('/',indexRouter);
app.use('/users', usersRouter);
app.use('/oauth',oAuthRouter);
app.use('/login_verification',loginVerification);

// React routes - Located in the client directory // 
app.use(express.static(path.join(__dirname, 'client'))); // Serve react files
app.use('/login',express.static(path.join(__dirname, 'client')))
app.use('/welcome',express.static(path.join(__dirname, 'client')))

App.js 组件文件中的 react App 函数将如下所示,定义您刚刚添加的告诉 express 用于 react 的路由。

function App() {
  return (
   <Router>
     <div className="App">
      <Switch>
        <Route exact path="/login" render={(props)=><Login/>}/>
        <Route exact path="/welcome" render={(props)=><Welcome/>}/>
      </Switch>
     </div>
   </Router> 
  );
}

在组件文件夹下有loginwelcome 的组件。现在导航到 http://MyWebsite/login 将提示 express 使用 react 路由,而例如导航到 http://MyWebsite/login_verification 将使用 express API 路由。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 2016-03-06
    • 1970-01-01
    相关资源
    最近更新 更多