11

We're developing a ReactJS application using Create-React-App, that is served from our Node/Express server that also serves API's. We deploy the whole server to Heroku using node/JS buildpack and trying to get the CRA build step npm run build in postinstall script from the node package.json file as suggested by @mars in this issue.

The issue is that Heroku deployment is failing with this error. Note that this error happen to me sometime locally but then a npm install from the web_app is solving the issue, but not when run in Heroku. I have two related questions:

  1. How to deploy to Heroku a Node/Express app that serves both APIs and a Create-React-App application? I can commit my build directory but this is really not the right way.
  2. Why the react-scripts are disappearing and I have to run multiple times the npm install.
2
  • 1
    Did you add the postinstall script? Can you post your package.json file? Did you run npm install -g webpack inside your command line? Commented Jan 27, 2018 at 3:23
  • Did you create your node server.js? Commented Jan 27, 2018 at 3:34

9 Answers 9

40

@johnnycon -

This was exactly the issue and I've received the answer from Mars in this github issue post:

@philjoseph, react-scripts is (by default) a devDependency for CRA apps, but Heroku Node buildpack has environment NODE_ENV=production which causes npm install to skip devDeps.

To install those devDeps too:

npm install --only=dev && npm install && npm run build

He also pointed to this excellent repo: https://github.com/mars/heroku-cra-node

I followed this and it works like a charm :)

Sign up to request clarification or add additional context in comments.

5 Comments

would be good to mark this as the answer so it appears at the top.
What if we use yarn? I tried: yarn install --only=dev && yarn install && npm run build but that did not seem to make changes to package lock file
Thank you, saved me another week of troubleshooting!
Definitely the best answer I have found on the internet
not the best, the best is for Alexander, easy and only 1 step!
16

Since you need "react-scripts" both in development and in production, you can simple move "react-scripts": "1.0.16" from "devDependencies" into "dependencies", so heroku doesn't ignore it.

1 Comment

This is the ticket. No need to over think it. Perfect answer if you ask me
4

For anyone in 2021, follow Alexander Cherednichenko's VERY SIMPLE advice.

Explanation.
As of October 2021, Create-React-App's react-scripts package has a ton of security vulnerability issues. I'd imagine a few people may run into their "fix" which suggests moving react-scripts to devDependencies. If you're deploying to Heroku, this will NOT work. Moving react-scripts to devDependencies will cause this error, since Heroku needs react-scripts to build the React app.
It'll be fine locally, and you'll be vulnerability free when you run npm audit --production
or yarn audit --production.
Ultimately, though, Heroku will demand react-scripts to be in the regular dependencies section.

The highest voted answer provides a great example repo by Mars Hall (a principal engineer at Heroku) for creating a React app that's served from a node backend. These days, though, it too includes react-scripts in the regular dependencies section of its react-ui/package.json file. In addition, since Create-React-App defaults to Yarn these days, the addition of npm install --only=dev will not run nor work (that I could tell based on the node buildpack log).
Moreover, it may add testing dependencies that your app definitely won't need in production.

Unfortunately, until Create-React-App decides to do some updates, it's best to just ignore the issues that npm audit brings up (at least the ones related to react-scripts). Since react-scripts is a build tool, it's extremely unlikely for any reported vulnerabilities to be exploited.

Comments

3

There's a very simple solution. Before running the start script, Heroku will run a build script if it's in your package.json.

"scripts": {
  "start": "node server.js",
  "build": "cd client/ && yarn install && yarn build"
}

Comments

2

Are react-scripts declared as a devDependency or regular dependency in package.json? Since you're building on Heroku and heroku is reading the env variable as production (I'm assuming here), it won't install react-scripts. Try moving react-scripts as a regular dependency and try again.

With other cloud providers, I likely wouldn't follow this path, but with Heroku, it's the path of least resistance I've found. This article goes into a little more detail on your scenario. https://originmaster.com/running-create-react-app-and-express-crae-on-heroku-c39a39fe7851

1 Comment

This was exactly the issue and I've received the answer from Mars in this github issue post
1

i was trying exactly the same thing, deploy a create-react-app project to heroku, and was getting react-scripts not found something....

Heroku reads the scripts into package.json and cannot execute them.

The key to overcome this issue is to 'create/publish' the 'scripts' folder, which by default create-react-app does not create it, just to keep things simple.

So by running the eject command $npm run eject, the scripts folder its created as long as the config folder.

After that you can execute again the heroku script e.g. $ git push heroku master and hopefully it wil deploy everything on Heroku.

More info about eject script on create-react-app documentation

Hope this helps, good luck.

Comments

1

Can you share how your Package.json file Scripts look? I actually deployed to Heroku yesterday and it seems to be working quite ok for me.

Maybe your dependencies are not added correctly in your package.json.

This is how my scripts look (if you don't have any scss/less/sass ignore the first 2 scripts):

"scripts": {
"build-css": "node-sass src/ -o src/",
"watch-css": "npm run build-css && node-sass src/ -o src/ --watch --recursive",
"start": "npm run start:server",
"watch": "npm-run-all --parallel watch-css start:*",
"start:server": "node server/server.js",
"start:client": "react-scripts start",
"build": "npm run build-css && react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"postinstall": "npm run build"}

When running in Development to take advantage of the Hotrealoding I run

npm run watch

And for PROD I run

npm run build

And then I deploy to Heroku. Try to check the logs from Heroku in a separate Terminal window so you can check what is wrong with your deployment.

Simply use heroku logs to display the last 100 lines of your logs.

Or to tail the logs in real-time: heroku logs -t.

1 Comment

The solution is basically in this line: "postinstall": "knex migrate:latest && if [ \"$NODE_ENV\" = production ]; then cd web_app/ && npm install --only=dev && npm install && npm run build; fi"
0

Specify Node Environment Tell heroku what version of heroku we want to use. By default heroku uses older version which will crash our app. you have 2 package.json files, one in client, another one is in the express server side. in express server side add this to package.json

"engines": {
    "node": "12.9.1",
    "npm": "6.10.2" },

Specify start script

 Instruct heroku what command it should run to start up our server. Add this to the server side package.json 

"start":"node index.js",

INSTALL HEROKU CLI

Install Heroku Cli

Sudo apt-get update
curl https://cli-assets.heroku.com/install-ubuntu.sh | sh  or sudo snap install heroku

In macos

brew install heroku cli

By default heroku uses a git based deployment procedure or workflow.

Git init
Git add . 
Git commit -m “initial commit”

Heroku login
Heroku create nameOfTheApp

 https://git.heroku.com/nameOfTheApp.git

This link is our deployment target. It is a git repository that we can push our local server to it.

Git remote add heroku https://git.heroku.com/nameOfTheApp.git

Git push heroku master

Comments

0

I had the same problem and happened to solve the problem by adding a few lines in the package.json (the one for the main project not the one in the client side) after seing @Daniel's comment.

What's happenning here is that Heroku is searching for the react scripts that can be used to install the dependecies and build the app on the client side. In my case both of those scripts were missing. In fact this is how my scripts looked like when I had the problem :

  ...
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "build": "cd client && npm run build",
    "client": "cd client && npm start"
  },
  ...

Heroku was expecting the scripts "install-client" and "heroku-postbuild". I just added them and the error dissapeared :

  ...
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "build": "cd client && npm run build",
    "client": "cd client && npm start",
    "install-client": "cd client && npm install",
    "heroku-postbuild": "npm run install-client && npm run build"
  },
  ...

I hope this would help someone.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.