remy / nodemon

Monitor for any changes in your node.js application and automatically restart the server - perfect for development
http://nodemon.io/
MIT License
26.13k stars 1.72k forks source link

ts-node should not be default when `--import` flag is present #2157

Closed joeldenning closed 6 months ago

joeldenning commented 6 months ago

See related https://github.com/remy/nodemon/commit/f7816e445b61e77dd57d5c9ccf5fa0be4f9b18a7 and https://github.com/remy/nodemon/issues/2083. In NodeJS 20, it's possible to customize loader hooks via both the --loader and --import flags, but nodemon currently only accounts for the --loader hook

Expected behaviour

When the --import NODE_OPTIONS flag is present, ts-node should not be the default program to execute .ts and .tsx files.

Actual behaviour

When the --import NODE_OPTIONS flag is present, ts-node is the default program to execute .ts and .tsx files. Note that this can be worked around by creating a nodemon.json file with the following:

{
  "execMap": {
    "ts": "node",
    "tsx": "node"
  }
}

Steps to reproduce

  1. Create a .register.mjs file that uses https://github.com/node-loader/node-loader-babel to compile typescript files
    
    import { register } from 'node:module';

register("@node-loader/babel", import.meta.url);

2. Run a typescript program with nodemon:

```sh
"NODE_OPTIONS=--import ./register.mjs" nodemon main.ts

Note the error that occurs:

sh: ts-node: command not found
[nodemon] failed to start process, "ts-node" exec not found
[nodemon] Error
    at Bus.<anonymous> (/Users/joeldenning/code/baseplate-web-app/node_modules/.pnpm/nodemon@2.0.20/node_modules/nodemon/lib/nodemon.js:158:25)
    at Bus.emit (node:events:526:35)
    at ChildProcess.<anonymous> (/Users/joeldenning/code/baseplate-web-app/node_modules/.pnpm/nodemon@2.0.20/node_modules/nodemon/lib/monitor/run.js:190:11)
    at ChildProcess.emit (node:events:514:28)
    at ChildProcess._handle.onexit (node:internal/child_process:294:12)
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): backend/**/* migrations frontend/**/* docs/**/*
[nodemon] watching extensions: tsx,ts,js,md,mdx,ejs
--------------
node: v20.8.0
nodemon: 2.0.20
command: /Users/joeldenning/n/bin/node /Users/joeldenning/code/baseplate-web-app/node_modules/nodemon/bin/nodemon.js --dump --signal SIGINT backend/Server.ts --watch backend --watch migrations --watch frontend --watch docs --ext tsx,ts,js,md,mdx,ejs
cwd: /Users/joeldenning/code/baseplate-web-app
OS: darwin arm64
--------------
{
  run: false,
  system: { cwd: '/Users/joeldenning/code/baseplate-web-app' },
  required: false,
  dirs: [
    '/Users/joeldenning/code/baseplate-web-app/backend',
    '/Users/joeldenning/code/baseplate-web-app/frontend',
    '/Users/joeldenning/code/baseplate-web-app/docs'
  ],
  timeout: 1000,
  options: {
    dump: true,
    signal: 'SIGINT',
    watch: [
      'backend',
      'migrations',
      'frontend',
      'docs',
      re: /backend|migrations|frontend|docs/
    ],
    execMap: { py: 'python', rb: 'ruby', ts: 'ts-node' },
    ignore: [
      '**/.git/**',
      '**/.nyc_output/**',
      '**/.sass-cache/**',
      '**/bower_components/**',
      '**/coverage/**',
      '**/node_modules/**',
      re: /.*.*\/\.git\/.*.*|.*.*\/\.nyc_output\/.*.*|.*.*\/\.sass\-cache\/.*.*|.*.*\/bower_components\/.*.*|.*.*\/coverage\/.*.*|.*.*\/node_modules\/.*.*/
    ],
    monitor: [
      '/Users/joeldenning/code/baseplate-web-app/backend/**/*',
      'migrations',
      '/Users/joeldenning/code/baseplate-web-app/frontend/**/*',
      '/Users/joeldenning/code/baseplate-web-app/docs/**/*',
      '!**/.git/**',
      '!**/.nyc_output/**',
      '!**/.sass-cache/**',
      '!**/bower_components/**',
      '!**/coverage/**',
      '!**/node_modules/**'
    ],
    ignoreRoot: [
      '**/.git/**',
      '**/.nyc_output/**',
      '**/.sass-cache/**',
      '**/bower_components/**',
      '**/coverage/**',
      '**/node_modules/**'
    ],
    restartable: 'rs',
    colours: true,
    stdin: true,
    runOnChangeOnly: false,
    verbose: false,
    stdout: true,
    watchOptions: {},
    execOptions: {
      script: 'backend/Server.ts',
      exec: 'ts-node',
      args: [],
      scriptPosition: 0,
      nodeArgs: undefined,
      execArgs: [],
      ext: 'tsx,ts,js,md,mdx,ejs',
      env: {}
    }
  },
  load: [Function (anonymous)],
  reset: [Function: reset],
  lastStarted: 0,
  loaded: [ '/Users/joeldenning/code/baseplate-web-app/nodemon.json' ],
  watchInterval: null,
  signal: 'SIGINT',
  command: {
    raw: { executable: 'ts-node', args: [ 'backend/Server.ts' ] },
    string: 'ts-node backend/Server.ts'
  }
}
--------------
edosrecki commented 6 months ago

Same here, I want to use node --import tsimp/import, instead of node --loader ts-node/esm. Currently, I am using a mentioned workaround with execMap:

{
  "ext": "ts",
+  "execMap": {
+    "ts": "node"
+  },
  "env": {
    "NODE_OPTIONS": "--import tsimp/import"
  }
}
remy commented 6 months ago

Sorry for the late reply. I've tried to compose multiple replies, and it keeps changing drastically as I start to fully understand the problem (aka: "fully read the ticket"!).

Would it make sense to add support for --import (in addition to --loader)? Is it as simple as that?

I'm really not sure what the broader impact is, but I'm guessing (because I've not used these myself) that import is ESM "require this module" and loader is commonjs "(actually) require this module".

My gut says that since adding the original loader support didn't mess up anyone's day, I'd guess adding import support would land in the same way.

Just let me know (hopefully with a considered response) and I'll get the change in and released :+1:

edosrecki commented 6 months ago

@remy

I think that's correct, to support both flags.

Usage of --loader is discouraged (in fact it logs warnings in some Node.js versions), and it is recommended to use --import flag instead.

You can read more in official Node.js docs:

remy commented 6 months ago

I just pushed the code but for some reason it's not deploying, so I'll try to sort that out this evening.

github-actions[bot] commented 6 months ago

:tada: This issue has been resolved in version 3.0.3 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

remy commented 6 months ago

That's live