Heroku提供create-react-app开发构建而非生产构建

5
我刚开始使用create-react-app,结合了redux和react-router-dom,并将其推送到Scalingo和Heroku上,但两者都以开发构建来提供服务。我的redux-logger是开启的,React开发工具提示如下:
“此页面正在使用React的开发版本。”
我没有进行任何自定义部署,只是推送到生产环境。我做错了什么?
Scalingo部署日志:
<-- Start deployment of ***** -->
       Fetching source code
       Fetching deployment cache
-----> Creating runtime environment

       NPM_CONFIG_LOGLEVEL=error
       NPM_CONFIG_PRODUCTION=true
       NODE_VERBOSE=false
       NODE_ENV=production
       NODE_MODULES_CACHE=true
-----> Installing binaries
       engines.node (package.json):  unspecified
       engines.npm (package.json):   unspecified (use default)
       engines.yarn (package.json):  unspecified (use default)

       Resolving node version 8.x...
       Downloading and installing node 8.15.0...
       Using default npm version: 6.4.1
       Resolving yarn version 1.x...
       Downloading and installing yarn (1.14.0)...
       Installed yarn 1.14.0
-----> Restoring cache
       Loading 2 from cacheDirectories (default):
       - node_modules
       - bower_components (not cached - skipping)
-----> Building dependencies
       Installing node modules (yarn.lock)
       yarn install v1.14.0
       [1/4] Resolving packages...
       success Already up-to-date.
       Done in 0.60s.
       Running build (yarn)
       yarn run v1.14.0
       $ react-scripts build
       Creating an optimized production build...
       Compiled successfully.

       File sizes after gzip:

       161.32 KB  build/static/js/2.21f749f2.chunk.js
       1.15 KB    build/static/js/main.e65e7a00.chunk.js
       761 B      build/static/js/runtime~main.fdfcfda2.js

       The project was built assuming it is hosted at the server root.
       You can control this with the homepage field in your package.json.
       For example, add this to build it for GitHub Pages:

       "homepage" : "http://myname.github.io/myapp",

       The build folder is ready to be deployed.
       You may serve it with a static server:

       yarn global add serve
       serve -s build

       Find out more about deployment here:

       https://facebook.github.io/create-react-app/docs/deployment

       Done in 7.79s.
-----> Caching build
       Clearing previous node cache
       Saving 2 cacheDirectories (default):
       - node_modules
       - bower_components (nothing to cache)
-----> Build succeeded!
 Build complete, shipping your container...
 Waiting for your application to boot... 
 <-- https://*****.scalingo.io -->

package.json:

{
  "name": *****,
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@sentry/browser": "^4.5.4",
    "husky": "^1.3.1",
    "lint-staged": "^8.1.3",
    "prettier": "^1.16.4",
    "prop-types": "^15.7.1",
    "react": "^16.8.1",
    "react-dom": "^16.8.1",
    "react-redux": "^6.0.0",
    "react-redux-i18n": "^1.9.3",
    "react-router-dom": "^4.3.1",
    "react-scripts": "2.1.5",
    "redux": "^4.0.1",
    "redux-logger": "^3.0.6",
    "redux-promise": "^0.6.0",
    "redux-thunk": "^2.3.0"
  },
  "lint-staged": {
    "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
      "prettier --single-quote --trailing-comma all --write",
      "git add"
    ]
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  }
}


你的服务器是否指向从react-scripts build生成的/build或/prod文件夹?它可能指向项目源代码中的index.html文件。 - Oscar W
3个回答

13

在Heroku服务器中,将运行package.json文件中给定的start脚本。默认情况下,使用create-react-app时,start脚本将以开发模式运行应用程序。

为了从构建文件夹中运行优化的应用程序,您需要编写一个服务器。您可以使用以下代码来创建一个简单的服务器。请确保将其保存在名为server.js的文件中,并将其放置在存储库的根目录中。

const express = require('express');
const favicon = require('express-favicon');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();
app.use(favicon(__dirname + '/build/favicon.ico'));
// the __dirname is the current directory from where the script is running
app.use(express.static(__dirname));
app.use(express.static(path.join(__dirname, 'build')));
app.get('/ping', function (req, res) {
  return res.send('pong');
});
app.get('/*', function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(port);

你需要添加以下依赖项:

  1. express
  2. express-favicon
  3. path

最后,更改 package.json 文件以使启动脚本运行服务器。为了保持能够运行开发模式,你可以提供另一个脚本。

"scripts": {
  "build": "react-scripts build",
  "devstart": "react-scripts start",
  "start": "node server.js"
  "test": "react-scripts test",
  "eject": "react-scripts eject"
}

将更改推送到Heroku,您的应用程序应该正常运行。

您可以在此文章中阅读更多相关信息。
https://medium.com/jeremy-gottfrieds-tech-blog/tutorial-how-to-deploy-a-production-react-app-to-heroku-c4831dfcfa08


你说得对,我必须使用Express编写一个server.js文件,但最终我的解决方案与你的有点不同。我没有修改脚本,而是更喜欢编写一个Procfile,其中包含 web: node server.js - adesurirey
1
完全按照所写的方式运行,没有做任何更改。 - Vadim

3

我的工作解决方案就是修改package.json文件如下:

 "scripts": {
       "heroku-prebuild": "npm install -g serve",
       "devstart": "react-scripts start",
       "start": "serve -s build",
       "build": "react-scripts build",
       "eject": "react-scripts eject",
 },

通过使用 "heroku-prebuild",您可以安装服务器而无需上传任何其他代码。

1
这个解决方案对我造成了一些问题,它无法正确导入CSS。另一个解决方案是创建一个server.js文件通过express来提供应用程序,这个方案对我完美地起作用了。 - Sydney C.

1

我添加了一个 Procfile 文件,包含正确的执行命令,并在 package.json 脚本中包含了 Heroku 的预构建步骤:

package.json:

 "scripts": {
       "heroku-prebuild": "npm install -g serve",  // <- NEW 
       "start": "react-scripts start",
       "build": "react-scripts build",
       "test": "react-scripts test",
       "eject": "react-scripts eject",
 },

Procfile

web: serve -s build

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接