3
votes

I'm new to create-react-app.

I just made a fresh setup with redux and react-router-dom then pushed it to Scalingo then Heroku and both of them ends up serving the development build. My redux-logger is on and React dev tools warns that :

This page is using the development build of React. ????

I did not do anything to customize deployment, just pushed to production.

What am I doing wrong ?

Scalingo deployment logs :

<-- 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"
    }
  }
}

3
Is your server pointing towards the /build or /prod folder that is made from react-scripts build? It may be pointing to the index.html file in the source of your project. - Oscar W

3 Answers

8
votes

The server in Heroku will run the start script given in the file package.json. By default, when using create-react-app the start script will run the app in development mode.

In order to run the optimized application from the build folder you will need to write a server. You can use the following code for a simple server. Make sure to save it a file named server.js and place it in the root of the repository.

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);

You will need to add the following dependencies:

  1. express
  2. express-favicon
  3. path

Finally, change the package.json so the start script runs the server. To keep being able to run the development mode, you can provide another script for it.

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

Push the changes to Heroku and your application should run properly.

You can read more about it in this article.
https://medium.com/jeremy-gottfrieds-tech-blog/tutorial-how-to-deploy-a-production-react-app-to-heroku-c4831dfcfa08

2
votes

My working solution is just modifying the package.json to:

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

With "heroku-prebuild" you can install the serve wihtout having to upload any additional code.

1
votes

I added a Procfile with the correct execution command and included a prebuild step for heroku in package.json scripts:

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