Closed breathe closed 4 years ago
Hello @breathe 😄
If we have a node_modules/
problem, then the Node buildpack would be the responsible party. This create-react-app-buildpack does not do the npm magic itself.
The observed unbound growth is probably a side-effect of Node buildpack changes made to cache and improve build time over the years. At conflict with that is heroku-buildpack-monorepo manipulating the build paths in unofficial and (at this point) untested ways.
The best solution I have for you is break up your monorepo, so that each Heroku app has its own repo. That's really the only supported way to use Heroku.
I personally use monorepos via Terraform configuration, which allows combining multiple apps and other cloud services together within a single repo. Terraform is pretty sweet, but it's not officially supported either, so will find different issues with it!
Preventing the node buildpack from caching node_modules is good enough for now for me ...
heroku config:set NODE_MODULES_CACHE=false --app appname
Hi @breathe I'm having difficulties with getting the create-react-app-buildpack and heroku-buildpack-monorepo work together. In which order you have the buildpacks? Or is there something else I should take into consideration to be able to run my cra-app on heroku?
My dir structure (important parts in parenthesis) is like this:
The api (backend) part runs smoothly, so I guess it is something related to the create-react-app. So since you have been able to run the stack successfully, could you provide a tip how to gain that? :D
Config variable is also set as required like this: APP_BASE=client
And here's my buildpacks:
Sharing my experience to deploy a CRA as a package inside a monorepo (yarn workspaces) I managed to get it working smoothly as following:
Summary first:
create a very simple express server to serve your CRA app, as following
const path = require('path');
const express = require('express');
const app = express();
const port = Number(process.env.PORT) || 3000; // read process.env.PORT from heroku environment
app.use(express.static(path.join(__dirname, 'build'))); // here we serve all the statics
app.get('/', (_, res) => {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(port, () => {
console.log(`Up and running on http://localhost:${port}`);
});
make sure to update (__dirname, 'build', 'index.html')
and path.join(__dirname, 'build')
based on your server
location, i use server.js
right on the root of my CRA for simplicity.
Heroku by default will look for package.json->scripts->build but only at the root package.json In order to make this work, you need to pass that through the root package.json
// root package.json
"scripts": {
"build": "yarn workspaces run build", // this will trigger all "build" scripts for all packages into your monorepo (more on that later)
}
// your CRA package.json
{
"build": "react-scripts build"
}
add Procfile into the root of your package (example, /packages/mywebapp/Procfile)
use heroku-buildpack-multi-procfile
under your heroku app settings create env var PROCFILE=path/to/your/app/Procfile
Here's my Procfile
web: node packages/web/server.js
I use only two buildpacks:
let's say you have 2 or more apps, and you only want to run package.json scripts.build
for the only one you are deploying:
you could do the following:
define env var WEB_APP_ENV=true
into your heroku app
use if-env and npm-run-all on your root package.json
{
"build": "run-p build:*",
"build:web": "if-env WEB_APP_ENV=true && yarn workspace my-web-app run build || echo 'skip build:web'",
}
this way, only one application will be deployed based on env variables.
here's a summary of folder/file structure:
package.json (root package.json)
packages
web
package.json
server.js
src
Procfile
build (generated on CRA build)
api
Procfile
server.js
...
and here're some screenshots that could help:
hope it's not complex, and simple to follow! it took me around 1 hour to deploy my CRA! 🚀
I have a create-react-app app in a subdirectory of another project which is also deployed via heroku ...
Heroku's mono-repo support isn't great -- but I'm using the https://github.com/lstoll/heroku-buildpack-monorepo buildpack to independently deploy a create-react-app app from a sub-directory with APP_BASE referring to the root directory of my create-react-app project.
I'm seeing the size of my dyno images grow without bounds -- and eventually have to clear the heroku cache.
It appears the contents of node_modules/.cache are growing without bound across builds ...
Here's a heatmap of files in my create-react-app slug
Everything to left of the white line are files within