Search code examples
reactjsherokucreate-react-appmonorepo

How To Deploy React App w/ Shared Code In Monorepo To Heroku


I'm using react-app-rewired & customize-cra to setup a multi-project monorepo with shared TypeScript code, without ejecting from create-react-app (the setup is described in this answer). The layout is like:

/my-project
|--- /frontend  <-Contains the create-react-app
|--- /shared    <-Contains some typescript source, used by the CRA
...

It works great locally. The only thing I'm unable to figure out is how to get it deployed to Heroku:

  1. If I use Git to just push the 'frontend' subdirectory (git subtree push --prefix frontend heroku master), the Heroku build of course fails, because it cannot find the source files in /shared - those weren't even pushed to the server.
  2. I tried using the monorepo buildpack as described here, but the result was the same. Build failed, couldn't find source files in /shared.
  3. I've tried the "hacky" solution in the comment here: setting "postinstall": "npm install --prefix frontend in package.json. Although it seemed to build, accessing https://myap123.herokuapp.com and https://myap123.herokuapp.com/frontend yield 404.
  4. I also tried the solution in the comment here: putting release: cd frontend && npm install && npm run build in the procfile. Same behavior: it seems to build, but is not accessible from the browser (404).

While there are many resources about deploying projects from a monorepo, and many others about sharing code between React & Node projects, I've been unable to find anything that actually works for both: share code, and deploy the projects that reference that code to Heroku. At this point, I'm just focused on trying to deploy the frontend.

Any help would be greatly appreciated.


Solution

  • The simple answer (from this thread) is that Heroku provides no proper way to run in a subdirectory. Any solution will be a hack, and those will vary depending on your project layout.

    In my case, I got it working by putting a package.json in the root of the repo with:

     {
         "scripts": {
           "postinstall": "npm install --prefix backend && npm run build --prefix backend",
           "start": "node backend/dist/app.js"
         }
       }
    

    This did not require a procfile. If it's a typescript project, make sure the backend's package.json's script tag has "build": "tsc".

    For the frontend, I gave up on Heroku. Instead, I just deployed the frontend to Netlify, which lets you easily deploy from a (pre-built) subdir. So between using Netlify for frontend & the above hack for backend, I have a hacked-together working stack, until Heroku hopefully gets around to properly letting you specify a subdirectory from which to run (they claim they've been waiting for NPM Workspaces, which was completed as of NPM 7).