javascript - 我在 heroku 上的反应应用程序打开主页但不会打开其他页面
问题描述
我的 react 应用程序在本地运行良好,并部署到 heroku。但是,从主页上,任何指向另一个页面的链接都会显示一个空白页面,上面有“未找到”。没有其他错误消息。
这是我的服务器端 package.json 文件:
{
"name": "portfolio-generator",
"version": "1.0.0",
"description": "",
"main": "server.js",
"engines": {
"node": "12.16.x"
},
"dependencies": {
"axios": "^0.19.2",
"bootstrap": "^4.5.0",
"concurrently": "^5.2.0",
"express": "^4.17.1",
"if-env": "^1.0.4",
"mongoose": "^5.9.13",
"nodemon": "^2.0.4",
"react-bootstrap": "^1.0.1",
"react-bootstrap-validation": "^0.1.11",
"styled-components": "^5.1.0"
},
"devDependencies": {},
"scripts": {
"start": "if-env NODE_ENV=production && npm run start:prod || npm run start:dev",
"start:prod": "node server.js",
"start:dev": "concurrently \"nodemon --ignore 'client/*'\" \"npm run client\"",
"client": "cd client && npm run start",
"build": "cd client && npm run build",
"heroku-postbuild": "cd client && npm install && npm install --only=dev --no-shrinkwrap && npm run build",
"seed": "node ./seeders/seed.js",
"install": "cd client && npm install"
},
"repository": {
"type": "git",
"url": "git+https://https://github.com/...../jtsy.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://https://github.com/...../jtsy/issues"
},
"homepage": "https://https://github.com....../jtsy#readme"
}
这是客户端的 package.json:
{
"name": "portfolio-generator",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:3001/",
"dependencies": {
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"axios": "^0.19.2",
"bootstrap": "^4.4.1",
"react": "^16.13.1",
"react-bootstrap": "^1.0.1",
"react-bootstrap-validation": "^0.1.11",
"react-dom": "^16.13.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.1",
"semantic-ui-css": "^2.4.1",
"semantic-ui-react": "^0.88.2",
"styled-components": "^5.1.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
服务器.js
const express = require("express");
import npm package mongoose, the ODM for mongo database
const mongoose = require("mongoose");
const routes = require("./routes");
const app = express();
// set the port for mongo connection to 3001 in development mode
const PORT = process.env.PORT || 3001;
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
app.use(routes);
// Connect to the Mongo DB (portfolio_db)
mongoose.connect(
process.env.MONGODB_URI || "mongodb://localhost/portfolio_db",
{
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
}
);
app.listen(PORT, () =>
console.log(` ==> API Server now listening on PORT ${PORT}!`)
);
根据一些研究,我添加了一个 static.json 文件:
{
"root": "build/",
"clean_urls": false,
"routes": {
"/**": "index.html"
}
}
服务器端的 routes/index.js 中有一个默认路由:
....
router.use("*", (req, res) =>
res.sendFile(path.join(__dirname, "../client/src/index.html"))
);
module.exports = router;
在 App.js(react top 组件)中,react router 是这样使用的:
...
<Router>
<Switch>
<DevDataContext.Provider value={devDataProvider}>
<SetupContext.Provider value={setupProvider}>
{setup.initialized ? (
<Route exact path="/" component={Home} />
) : (
<Route exact path="/" component={Signin} />
)}
<Route exact path="/contact" component={Contact} />
<Route exact path="/about" component={About} />
<Route exact path="/Developer" component={Developer} />
<Route exact path="/Signin" component={Signin} />
</SetupContext.Provider>
</DevDataContext.Provider>
<Route component={NoMatch} />
</Switch>
</Router>
...
有了这一切,我处于停顿状态。主页加载并刷新,但不会重定向到任何地方。
编辑: index.html 的路径是错误的。它位于“client”下的“public”文件夹中,因此在 routes/index.js 中,它现在是:
router.use("*", (req, res) =>
res.sendFile(path.join(__dirname, "../client/public/index.html"))
);
现在我得到的只是heroku页面上的一个空白屏幕。我认为我的问题是基于路由的定义方式,但我仍然无法弄清楚。
我的文件夹结构是:
/projectname
server.js
package.json
...
/client
package.json
/public
index.html
...
/src
App.js
index.js
...
/components
/pages
/controllers
/models
/routes
index.js (this is where the path to index.html is defined)
/api
index.js
...
编辑 #2 解决方案 在 server.js 中进行了一些关键更改。最重要的是添加“路径”包(菜鸟错误)。我还必须将“app.use(routes)”放在默认反应路由代码之前,该代码现在位于“生产”代码块之外。
const path = require('path');
const express = require("express");
const mongoose = require("mongoose");
const routes = require("./routes");
const app = express();
// set the port for mongo connection to 3001 in development mode
const PORT = process.env.PORT || 3001;
// Configure body parsing for AJAX requests
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// Serve up static assets
**if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
app.use(routes);
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});**
// Connect to the Mongo DB (portfolio_db)
mongoose.connect(
process.env.MONGODB_URI || "mongodb://localhost/portfolio_db",
{
useCreateIndex: true,
useNewUrlParser: true,
useUnifiedTopology: true,
}
);
// Start the API server on port 3001
app.listen(PORT, () =>
console.log(` ==> API Server now listening on PORT ${PORT}!`)
);
我还删除了 /routes/index.js 中对默认反应路由的引用
解决方案
找到解决方案。对 server.js 的 3 处更改。添加:
const path = require('path')
忘记这一点绝对是一个新手错误!此外,修改代码以将默认反应路由从“生产”代码块中提取出来,并将其放在 'app.use(routes) 下方,例如:
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
app.use(routes);
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "./client/build/index.html"));
});
我还从 /routes/index.js 中删除了默认的反应路由。
推荐阅读
- javascript - 如何在 NGINX 上重定向并将原始请求存储为 POST 变量?
- c# - Websocket 代码在控制台中有效,但在 winform 中无效
- regex - 每千位数
- python - 根据 dask 数据框中的条件更改列变量值
- java - 使用来自模型向量的数据(具有很少的属性),而无需在 JAVA 中的 WEKA API 中制作 ARFF 文件
- twilio - 查看使用 Twilio 函数生成的 twiml
- c# - 在 C# 中使用“浮动”结构解析 XML 并填充列表框
- c++ - 拓扑排序中的邻接表表示
- codenameone - 将 PropertyBusinessObjects 列表保存到存储中
- javascript - 如何在电子 renderer.js 文件中使用 Node.js 解析 JSON?