在部署到heroku时,我不知道如何让我的react应用程序(使用create-rect应用程序创建(工作。
没有heroku,一切都很好。我使用npm start
,它使用react-scripts start
来启动react应用程序,并且一切都按预期在本地运行。现在我想让应用程序在heroku上运行,我必须使用express将其内容提供给客户端。我试过了,但遗憾的是,我的浏览器一直是空白的。只是一个白色的屏幕,没有别的。甚至没有错误消息?!既不在控制台中,也不在浏览器的控制台中。
我的服务器结构如下:
- 公共
- favicon.ico
- index.html
- manifest.json
- 等等
- src
- App.css
- 应用程序.js
- index.css
- index.js
- 等等
- package-lock.json
- package.json
- Procfile
- server.js
这是我的server.js文件:
const path = require('path');
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'src')));
app.get('/', (req, res) => {
res.sendFile(path.join(publicPath, 'index.html'));
});
app.listen(port, () => {
console.log('Server is running on port ' + port);
});
文件里有错吗?或者我可能使用了错误的方法来启动服务器?
我见过有人使用node server.js
,有些人在一个终端中运行node server.js
,在另一个终端运行npm start
。还有一些只运行npm start
,但将package.json中的启动脚本更改为node server.js
。我想我在这一点上很困惑。所有这些命令之间有什么区别?
我能做些什么来解决这个问题?有人能帮我吗?或者你需要任何额外的代码见解来帮助我吗?
我的服务器.js
const express = require('express');
const http = require('http');
const path = require('path');
let app = express();
app.use(express.static(path.join(__dirname, 'build')));
const port = process.env.PORT || '8080';
app.set('port', port);
const server = http.createServer(app);
server.listen(port, () => console.log(`Running on :${port}`));
我的Procfile按照heroku:
web: node server.js
请注意,您应该有build
文件夹,heroku将在其中提取产品。此外,package.json.
我的包.json
{
"name": "my-app",
"version": "3.0.1",
"main": "index.js",
"license": "MIT",
"dependencies": {
"@amcharts/amcharts4": "^4.0.3",
"@amcharts/amcharts4-geodata": "^4.0.27",
"@babel/runtime": "7.0.0-beta.55",
"@date-io/moment": "^1.1.0",
"@material-ui/core": "^3.8.1",
"@material-ui/icons": "^3.0.1",
"array-move": "^1.0.0",
"autosuggest-highlight": "^3.1.1",
"axios": "^0.18.0",
"babel-preset-stage-2": "^6.24.1",
"bootstrap": "^4.1.3",
"bootstrap-v4-rtl": "^4.1.1-0",
"can-use-dom": "^0.1.0",
"chart.js": "^2.7.3",
"classnames": "^2.2.6",
"connected-react-router": "^6.2.1",
"cross-env": "^5.2.0",
"downshift": "^3.1.5",
"draft-js": "^0.10.5",
"draftjs-to-html": "^0.8.4",
"email-regex": "^3.0.0",
"express": "^4.17.1",
"history": "^4.7.2",
"install": "^0.10.1",
"isomorphic-fetch": "^2.2.1",
"jss-rtl": "^0.2.3",
"jwt-decode": "^2.2.0",
"luhn": "^2.3.0",
"material-ui-pickers": "^2.0.1",
"moment": "^2.22.2",
"node-sass": "^4.10.0",
"node_env": "^0.0.3",
"nprogress": "^0.2.0",
"package.json": "^2.0.1",
"path": "^0.12.7",
"prop-types": "^15.6.2",
"query-string": "^6.4.0",
"react": "^16.6.3",
"react-autosuggest": "^9.4.2",
"react-big-calendar": "^0.20.2",
"react-bootstrap-sweetalert": "^4.4.1",
"react-chartjs-2": "^2.7.4",
"react-circular-progressbar": "^1.0.0",
"react-ckeditor-component": "^1.1.0",
"react-color": "^2.17.0",
"react-custom-scrollbars": "^4.2.1",
"react-d3-speedometer": "^0.4.2",
"react-device-detect": "^1.6.1",
"react-dnd": "^6.0.0",
"react-dnd-html5-backend": "^6.0.0",
"react-dom": "^16.6.3",
"react-draft-wysiwyg": "^1.12.13",
"react-dropzone": "^4.2.9",
"react-google-maps": "^9.4.5",
"react-hot-loader": "^4.3.12",
"react-icons": "^3.2.2",
"react-intl": "^2.7.2",
"react-joyride": "^1.11.4",
"react-jss": "^8.6.1",
"react-jvectormap": "^0.0.4",
"react-loadable": "^5.5.0",
"react-notifications": "^1.4.3",
"react-number-format": "^4.0.4",
"react-paypal-express-checkout": "^1.0.5",
"react-placeholder": "^3.0.1",
"react-redux": "^6.0.0",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-select": "^2.1.1",
"react-simple-maps": "^0.12.1",
"react-slick": "^0.23.1",
"react-sortable-hoc": "^0.8.3",
"react-star-rating-component": "^1.4.1",
"react-swipeable-views": "^0.13.0",
"react-text-mask": "^5.4.3",
"reactstrap": "^6.5.0",
"recharts": "^1.3.6",
"recompose": "^0.30.0",
"redux": "^4.0.1",
"redux-logger": "^3.0.6",
"redux-persist": "^5.10.0",
"redux-saga": "^0.16.2",
"save": "^2.3.2",
"slick-carousel": "^1.8.1",
"typeface-roboto": "^0.0.54",
"underscore": "^1.9.1",
"url-search-params": "^1.1.0"
},
"scripts": {
"start": "cross-env NODE_PATH=src react-scripts start",
"build": "cross-env NODE_PATH=src react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"devDependencies": {
"bootstrap": "^4.1.3",
"node-sass": "^4.9.3",
"prettier": "^1.14.2",
"react-scripts": "2.1.1"
},
"browserslist": {
"development": [
"last 2 chrome versions",
"last 2 firefox versions",
"last 2 edge versions"
],
"production": [
">0.25%",
"not op_mini all",
"ie 11"
]
},
"engines": {
"node": ">=6.9.0",
"npm": ">= 3"
}
}
Heroku在部署时默认会运行npm run build
。在您的情况下,这是react-scripts build
。此脚本将把您的代码捆绑到一个build
文件夹中。
快递
这意味着您的Express中间件应该提供来自build
文件夹而不是src
文件夹的静态文件。
app.use(express.static(path.join(__dirname, 'src')));
应该是:
app.use(express.static(path.join(__dirname, 'build')));
(注意:我建议为这个process.env.STATIC_DIR
或类似的东西使用一个环境变量。这样你就可以很容易地在用于本地开发的src
和用于生产代码和部署的build
之间切换。(
程序文件
您的procfile说明在部署代码后应该运行哪个命令Heroku。知道Heroku运行npm run build
,您应该提供您的捆绑包,而不是源代码。
你可以这样更改你的procfile:
web:npm start
应为:
web:node server.js
这将运行server.js文件,该文件提供build
文件夹中的静态内容。
(注意:npm run start
仅用于本地开发。在部署web应用程序时,您应该只部署生产代码。(
(注意:您可以通过运行npm run build
来捆绑您的代码,并运行node server.js
来为其提供服务,从而在本地测试您的生产构建。(
是的,create-react-app
与Node的配合不太好。这就是我为修复部署所做的。
tl;dr
:由于您使用create-react-app
创建了react应用程序,因此需要使用不同的构建包,例如:github.com/mars/create-react-app-buildpack.git
Heroku文档中的工作流示例:
# You probably did this already
# Create the App
npm install -g create-react-app
create-react-app my-app
cd my-app
git init
# Then you worked on your app
# Now, create the app in heroku with this buildpack...
heroku create -b https://github.com/mars/create-react-app-buildpack.git
# ...or add the buildpack in Heroku's dashboard
# Add the files the buildpack bundled for you and deploy
git add .
git commit -m "react-create-app on Heroku"
git push heroku master
# To see your app
heroku open
Procfile(在根目录中(应该包含以下内容:
web: bin/boot
一旦在heroku的repo中,您就可以使用CLI启动web dyno
heroku ps:scale web=1:free
此时,您可以删除server.js文件:更多信息请点击此处:https://github.com/mars/create-react-app-buildpack#usage
希望这能有所帮助。干杯