Search code examples
node.jstypescriptheroku

How do I deploy my Typescript Node.js app to Heroku?


When testing locally I was previously running:

"build-live": "nodemon --exec ./node_modules/.bin/ts-node -r dotenv/config -- ./index.ts"

I then figured my Procfile should be something like:

web: ./node_modules/.bin/ts-node -- ./index.ts

But it says module 'typescript' not found, even when it is in package.json. I read in a few places that ts-node is not the way to go to deploy to Heroku, so I am not sure what to do.

UPDATE: I think I am supposed to compile it, so I tried:

web: ./node_modules/.bin/tsc --module commonjs --allowJs --outDir build/ --sourceMap --target es6 index.ts && node build/index.js

This succeeds, however when actually running it, a bunch of the libs I'm using get "Cannot find module '...'".


Solution

  • The command you've given Heroku is to launch the web "process" by compiling index.ts and dependencies and starting node at index.js. Depending on how things are timed, index.js might or might not exist at the time node starts.

    You need to already have your sources compiled by the time you want to start your app. For example, web should just be web: node index.js or similar.

    Each build process is different, so you need to figure that out for your own setup. But, suppose you have a classical setup where you push to git and then Heroku picks up that change and updates the app with the new slug. You could just compile things locally and include index.js and any other build output in the repository, for it to be available in the slug for Heroku to use.

    A better approach is to use a build server which has an integration with Heroku. After you do the build there, configure it to send the build results to Heroku. Travis has a straighforward setup like this. This way you don't need to include build outputs in your repository, which is considered an anti-pattern.


    On a sidenode, try using a tsconfig.json to keep the tsc configuration. It will save you from having to write such long command lines all over the place.