Search code examples
node.jstypescriptherokuheroku-cli

Heroku deployment Typescript


I am running an application that runs without any errors locally but when I deploy it on Heroku it deploys and finaly the app crashes.

my package.json.

    {
  "name": "app-server",
  "main": "index.ts",
  "scripts": {
    "start": "nodemon index.ts"
  },
  "engines": {
    "node": "10.16.x",
    "npm": "6.x"
  },

  "license": "ISC",
  "dependencies": {
    "@types/mongoose": "^5.7.7",
    "@types/node": "^13.9.2",
    "@types/react-router-dom": "^5.1.3",
    "config": "^3.3.2",
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "jsonwebtoken": "^8.5.1",
    "moment": "^2.29.1",
    "mongodb": "^3.5.5",
    "mongoose": "^5.10.9",
    "nodemon": "^2.0.5",
    "react-router-dom": "^5.1.2",
    "socket.io": "^2.3.0",
    "ts-node": "^8.10.2",
    "typescript": "^3.9.7"
  },
  "devDependencies": {
    "@types/config": "0.0.36",
    "@types/cors": "^2.8.6",
    "@types/express": "^4.17.3",
    "@types/jsonwebtoken": "^8.3.9"
  }
}

my tsconfig.json

{
  "compilerOptions": {
    "target": "es2018",
    "module": "commonjs",
    "lib": ["es2018", "esnext.asynciterable"],
    "skipLibCheck": true,
    "strict": true,
    "strictFunctionTypes": false,
    "strictPropertyInitialization": false,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

Procfile

web: npm start

Build Log of Heroku

 Node.js app detected
       
-----> Creating runtime environment
     
       NPM_CONFIG_LOGLEVEL=error
       NODE_ENV=production
       NODE_MODULES_CACHE=true
       NODE_VERBOSE=false
       
-----> Installing binaries
       engines.node (package.json):  10.16.x
       engines.npm (package.json):   6.x
       Resolving node version 10.16.x...
       Downloading and installing node 10.16.3...
       Bootstrapping npm 6.x (replacing 6.9.0)...
       npm 6.x installed      
-----> Restoring cache
       - node_modules
-----> Installing dependencies
       Installing node modules
       > [email protected] postinstall 
       > node bin/postinstall || exit 0
-----> Build
-----> Caching build
       - node_modules
-----> Pruning devDependencies
       removed 14 packages and audited 295 packages in 2.153s    
-----> Build succeeded!
-----> Discovering process types
       Procfile declares types -> web
-----> Launching...

Error log from Heroku


2020-11-04T09:55:14.920223+00:00 app[web.1]: /app/node_modules/ts-node/src/index.ts:434
2020-11-04T09:55:14.920224+00:00 app[web.1]: return new TSError(diagnosticText, diagnosticCodes)
2020-11-04T09:55:14.920225+00:00 app[web.1]: ^
2020-11-04T09:55:14.920420+00:00 app[web.1]: TSError: ⨯ Unable to compile TypeScript:
2020-11-04T09:55:14.920422+00:00 app[web.1]: index.ts(1,21): error TS7016: Could not find a declaration file for module 'express'. '/app/node_modules/express/index.js' implicitly has an 'any' type.
2020-11-04T09:55:14.920422+00:00 app[web.1]: Try `npm install @types/express` if it exists or add a new declaration (.d.ts) file containing `declare module 'express';`
2020-11-04T09:55:14.920423+00:00 app[web.1]: index.ts(8,20): error TS7016: Could not find a declaration file for module 'config'. '/app/node_modules/config/lib/config.js' implicitly has an 'any' type.
2020-11-04T09:55:14.920423+00:00 app[web.1]: Try `npm install @types/config` if it exists or add a new declaration (.d.ts) file containing `declare module 'config';`
2020-11-04T09:55:14.920424+00:00 app[web.1]: index.ts(9,18): error TS7016: Could not find a declaration file for module 'cors'. '/app/node_modules/cors/lib/index.js' implicitly has an 'any' type.
2020-11-04T09:55:14.920424+00:00 app[web.1]: Try `npm install @types/cors` if it exists or add a new declaration (.d.ts) file containing `declare module 'cors';`
2020-11-04T09:55:14.920425+00:00 app[web.1]: 

Anybody, please let me know what configuration needs to be changed for correct deployment


Solution

  • First of all, Heroku strips dev dependencies - that is why your deployment does not work. You can move everything to dependencies to solve that- but I really don't recommend it.

    You should remove nodemon from start command and use node index.js. But for that to work, you need to compile typescript to javascript. You can do it with tsc command.

    To sum up, you need:

    1. Create a build command, which runs tsc.
    {
        "scripts": {
            "build": "tsc"
        }
    }
    

    You can also use postinstall instead of build, which heroku calls.

    1. Update start command to use JS instead of TS.
    {
        "scripts": {
            "start": "node index.js"
        }
    }
    

    Read more: Deploying Typescript Node.js applications to Heroku