dividab / tsconfig-paths

Load node modules according to tsconfig paths, in run-time or via API.
MIT License
1.82k stars 104 forks source link

How to use tsconfig-paths with pm2? #93

Open charleylla opened 5 years ago

charleylla commented 5 years ago

I'm trying to deploy my typescript project with pm2, but the argument seems not working correctly.

Here is ecosystem.config.yml:

apps:
  - name: 'node-app'
    script: './src/main.ts'
    interpreter: './node_modules/.bin/ts-node'
    # they dont't work correctly below.
    interpreter_args: '-r tsconfig-paths/register'
    # args: '-T -r tsconfig-paths/register ./src/index.ts',
    # args: '-r ./node_modules/tsconfig-paths/register ./src/main.ts'
    # interpreter_args: ['--require=tsconfig-paths/register']
    # interpreter_args: '-P . -r ./node_modules/tsconfig-paths/register'
    kill_timeout: 10000
    instances: max
    exec_mode: cluster
    env:
      NODE_ENV: development

When I run pm2 start ecosystem.config.yml and check the logs then:

0|node-app | Error: Cannot find module '~framework/common/frame-util'
0|node-app |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
0|node-app |     at Function.Module._load (internal/modules/cjs/loader.js:507:25)
0|node-app |     at Module.require (internal/modules/cjs/loader.js:637:17)
0|node-app |     at require (internal/modules/cjs/helpers.js:20:18)
0|node-app |     at Object.<anonymous> (/Users/zhaolin/__CODES__/__PERSONAL__/charley-nest-starter/script/ci/src/solution/gateway/auth/auth.service.ts:5:1)
0|node-app |     at Module._compile (internal/modules/cjs/loader.js:689:30)
0|node-app |     at Module.m._compile (/Users/zhaolin/.nvm/versions/node/v10.9.0/lib/node_modules/pm2/node_modules/ts-node/src/index.ts:473:23)
0|node-app |     at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
0|node-app |     at Object.require.extensions.(anonymous function) [as .ts] (/Users/zhaolin/.nvm/versions/node/v10.9.0/lib/node_modules/pm2/node_modules/ts-node/src/index.ts:476:12)
0|node-app |     at Module.load (internal/modules/cjs/loader.js:599:32)

And my tsconfig.json is:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "rootDir": ".",
    "paths": {
      "~framework/*":["src/framework/*"],
      "~solution/*":["src/solution/*"],
      "~business/*":["src/solution/business/*"],
      "~dto/*":["src/solution/dto/*"],
      "~entities/*":["src/solution/entities/*"],
      "~/*":["src/*"]
    }
  },
  "exclude": ["node_modules", "dist"]
}

It seems that the paths alias are not working properly. It works well without pm2(this is a nestjs project):

...
    "start": "rimraf dist && cross-env NODE_ENV=development ts-node -r tsconfig-paths/register src/main.ts",
...

Can anyone help me with this problem? Thanks.

StephanBijzitter commented 4 years ago

Yeah I also had some trouble, the dirty way is the easiest way and for me it works. Forget about interpreter, interpreter_args, args, just all put it in the script value:

script: './node_modules/.bin/ts-node -r tsconfig-paths/register ./src/main.ts'

hooper-hc commented 4 years ago

Yeah I also had some trouble, the dirty way is the easiest way and for me it works. Forget about interpreter, interpreter_args, args, just all put it in the script value:

script: './node_modules/.bin/ts-node -r tsconfig-paths/register ./src/main.ts'

not good

hooper-hc commented 4 years ago

pm2 start bootstrap.js --node-args="-r tsconfig-paths/register"

hooper-hc commented 4 years ago

pm2 start bootstrap.js --node-args="-r tsconfig-paths/register"

@charleylla

avetisk commented 3 years ago

For those still having troubles with pm2 obscure arguments handling you can use this solution: https://github.com/Unitech/pm2/issues/4528#issuecomment-753464213 (

This is might not be the most elegant way to handle it, but hey, it just works and is simple and straightforward.

jonit-dev commented 3 years ago

On my case it was a little bit more complex because I was pointing to JS in production (so my tsconfig.json needed to use baseUrl as ./dist/src and not ./src). Locally I'm running on TS, so the issue was only in prod.

To solve it...

my package.json

    "start:prod": "pm2 start pm2.json --no-daemon",

my pm2.json - I had to add a custom register-paths.js file here, on my node_args

{
  "apps": [
    {
      "name": "psa-api",
      "script": "./dist/src/server.js",
      "merge_logs": true,
      "max_restarts": 20,
      "instances": 4,
      "node_args": "-r dotenv/config -r ./register-paths.js"
    }
  ]
}

register-path.js file

const path = require("path");
const tsConfig = require("./tsconfig.json");
const tsConfigPaths = require("tsconfig-paths");

const baseUrl = tsConfig.compilerOptions.baseUrl || ".";
const outDir = tsConfig.compilerOptions.outDir || ".";

const env = process.env.ENV;

let baseUrlPath;
if (env === "Production" || env === "Staging") {
  baseUrlPath = path.resolve(outDir, baseUrl);
} else {
  baseUrlPath = baseUrl;
}

const explicitParams = {
  baseUrl: baseUrlPath,
  paths: tsConfig.compilerOptions.paths,
};
tsConfigPaths.register(explicitParams);

Hope it helps! It took me 2 hours to figure it out. :)

matheusdavidson commented 2 years ago

For those still having troubles with pm2 obscure arguments handling you can use this solution: Unitech/pm2#4528 (comment) (

This is might not be the most elegant way to handle it, but hey, it just works and is simple and straightforward.

This worked for me on getting pm2 to work with tsconfig-paths/register, Thank you