Inspired by the awesome timanovsky/subdir-heroku-buildpack project. We created this buildpack because we often have projects that require multiple directories, and Tim's project only supported keeping a single directory. We also need to handle some additional package.json
tweaking that is specific to Node.js & Heroku.
As an example, consider the following repository structure:
/
core/
Contains a shared codebase that is used by both theweb
andadmin
projects.web/
Contains the project for serving a headless public website. Dependent on thecore
project.admin/
Contains the project for serving a private administration site. Also dependent on thecore
project. The public website must not have any knowledge or reference to thisadmin
site's existence.
In this case, we need that core
library to survive when deploying the web
and admin
sites to Heroku, since the npm run build
command for both admin
and web
relies on that core
library existing at build-time. Additionally, we need the ability to instruct Heroku which project to launch via a Config variable.
- Have your repository mirror the directory structure referenced above. The exact folder names are not important; you can name them however you like.
- Make sure your projects
package.json
all have abuild
andstart
script entered. They can be empty, but they must exist. - Log into Heroku & create two Heroku Config Vars in your project:
BUILDPACK_START
points to the directory in your repository that contains thepackage.json
to run. This config allows Heroku to be configured to launch one of many projects in the repository. In our example above, this would get set toadmin
for the admin project, andweb
for the public project.BUILDPACK_KEEP
is a;
-delimited list that includes all of the directories to retain. In our example case above, to configure thepublic
site this would get set toweb;core
. On theadmin
site, this would get set toadmin;core
.BUILDPACK_BUILD_COMMAND
is optional. It defaults tonpm install && npm run build
, but can be overridden if your project has a specific command that needs to execute. After theBUILDPACK_BUILD_COMMAND
is run, your app should be able tonpm run start
.
- Set this buildpack as the first item in the buildpack chain. Paste in the Git URL
https://github.com/space150/node-subdir-heroku-buildpack.git
. We recommend appending a specific commit hash to this Git URL so that any future changes we make to themain
branch do not impact your project. We fully reserve the right to make breaking changes at any time without any advance warning or notification.
- Creates a new
package.json
file on the root of the build artifact that delegates thebuild
andstart
commands to the configuredBUILDPACK_START
directory. The buildpack also attempts to set the{ engines: { node }}
value in this new rootpackage.json
file to match whatever is entered in yourBUILDPACK_START/package.json
file. - Takes the configured
BUILDPACK_KEEP
directories and copies them to the root of the build artifact. - Deletes everything in the Heroku build directory.
- Copies the build artifact into the now-empty Heroku build directory.
- Deletes the build artifact, leaving the final files in the Heroku build directory.
- Create some local directories to mirror the Heroku
build
,cache
, andenv
buildpack directory. On my machine, it looks like:- Build:
/Users/developer/dev/node-subdir-heroku-buildpack/.test/build
- Cache:
/Users/developer/dev/node-subdir-heroku-buildpack/.test/cache
- Env:
/Users/developer/dev/node-subdir-heroku-buildpack/.test/env
- Build:
- Copy your repository into your configured
build
directory. - Create
BUILDPACK_START
andBUILDPACK_KEEP
files in yourenv
buildpack directory. The contents of each file should be the values you want the buildpack to use. - While testing, it is recommended to create a
BUILDPACK_DEV
file in theenv
buildpack directory as well to disable the normal cleaning process. If you don't do this, you will have to clear out & re-copy your repository files in thetest/build
directory after each test, and on large repositories this can take significant time. - Run the
./bin/compile
script passing in the paths to each of your buildpack directories. Here's how it looks on my machine:sh ./bin/compile /Users/developer/dev/node-subdir-heroku-buildpack/.test/build /Users/developer/dev/node-subdir-heroku-buildpack/.test/cache /Users/developer/dev/node-subdir-heroku-buildpack/.test/env
- On Windows, you can use CMDER to emulate the shell script.
sh ./bin/compile C:/dev/node-subdir-heroku-buildpack/.test/build C:/dev/node-subdir-heroku-buildpack/.test/cache C:/dev/node-subdir-heroku-buildpack/.test/env
- Check the
build
orcache
directory to verify that your edits worked.