React-router URL's, Routing node/express & File Structure



文件结构

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

服务器.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 正在为我渲染它。我看了以下问题 反应路由器网址在手动刷新或写入时不起作用。我应该只做一个包罗万象并重新路由回主索引页面吗?这似乎会使书签无法使用。

编辑

以下是 2 个节点路由。

索引.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;

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

api  build  frontend  run_build.sh

api文件夹包含我对快速服务器的开发,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 使用某些路由进行 react,请在 expressserver.js文件中添加以下内容。

注意在添加反应路由之前,请先添加您的快速 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组件文件中的 reactApp函数将如下所示,定义您刚刚添加的路由,告诉 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将使用快速 API 路由。

最新更新