Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

watch mode in node.js 20 doesn't watch changes in non-entry files #246

Closed
1 task
o-alexandrov opened this issue May 26, 2023 · 15 comments · Fixed by esbuild-kit/esm-loader#64 or #310
Closed
1 task
Labels
bug Something isn't working outdated watch

Comments

@o-alexandrov
Copy link

o-alexandrov commented May 26, 2023

Bug description

watch mode works on node.js lts/hydrogen v18, but doesn't on 20+.

Reproduction

  1. Create 2 files
// file-1.ts - this is your entrypoint
import { example } from './file-2';
console.log(example);
// file-2.ts
export const example = 'Hello World!';
  1. Run tsx watch file-1.ts
  2. Modify value in file-2.ts
  3. Observe there's no rerun by tsx

Environment

System:
  OS: MacOS (currently latest 13.3)
  CPU: m1 pro
  Shell: zsh
Binaries:
  Node: 20.1.0
npmPackages:
  tsx: `3.12.7` (current latest)

Can you work on a fix?

  • I’m interested in opening a pull request to address this issue.
@o-alexandrov o-alexandrov added bug Something isn't working pending triage labels May 26, 2023
@lockieluke

This comment was marked as spam.

1 similar comment
@Billcountry

This comment was marked as spam.

@marvinroger
Copy link

I think it might be related to a bug in Chokidar, see vitejs/vite#12495

@o-alexandrov

This comment was marked as off-topic.

@marvinroger

This comment was marked as off-topic.

@privatenumber

This comment was marked as off-topic.

@marvinroger

This comment was marked as off-topic.

@privatenumber

This comment was marked as off-topic.

@Billcountry
Copy link

Found a temporary solution by using tsx as a loader instead:

node --watch --loader=tsx index.ts

@privatenumber
Copy link
Owner

If anyone is able to, please investigate what's causing this.

If it's chokidar, is there an issue tracked in their repository? We can consider swapping to a different watcher.

This was referenced Jul 15, 2023
@azhar1038
Copy link

I am using Node 20 in Windows and it seems to be working fine.
Is it just a MacOS issue?
Can anyone check if @parcel/watcher is working in mac or not?

@mkoreo
Copy link

mkoreo commented Jul 22, 2023

Experiencing identical issues on Linux.

thopop@Latitude5490: ~ $ uname -r
6.4.1-zen2-1-zen
thopop@Latitude5490: ~ $ node -v
v20.3.1

Found a temporary solution by using tsx as a loader instead:

node --watch --loader=tsx index.ts

I don't know why that works for you, but not using tsx directly gives me following error:

> tsc --build && dotenv -e .env.dev node --watch --loader=tsx src/server.ts --inspect=0.0.0.0:%SERVER_PORT%
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /usr/src/app/projects/backend/auth-service/src/server.ts

Edit: Does work as you described. I had an error in my command. (Missing -- after dotenv -e .env.dev)

@fspoettel
Copy link

fspoettel commented Jul 24, 2023

I don't think this is caused by chokidar, but a change to IPC that affects @esbuild-kit/esm-loader.

It appears as if we don't receive dependency messages from the esm-loader anymore. I patched in the following debug logs:

https://github.com/esbuild-kit/tsx/blob/9acf1c0eadcc6b7275b91a285acb180171b30d78/src/watch/index.ts#L86

runProcess.on('message', (data) => {
  console.log("received", data);

https://github.com/esbuild-kit/esm-loader/blob/332a0a0220dbb80de806ebb3a15ec7c3ce893bee/src/loaders.ts#L214

console.log("sending esm", url, "process.send", process.send);
if (process.send) {

https://github.com/esbuild-kit/cjs-loader/blob/3442035bd4d1251538141ecd3e80de1add41024a/src/index.ts#L55

console.log("sending cjs", filePath, "process.send", process.send);
if (process.send) {

This gives the following outputs (on macOS):

Node 18.17.0

> node-typescript-starter@0.0.0 dev
> tsx watch --clear-screen=false ./src/main.ts | pino-pretty

sending esm file:///Users/felix/code/node-ts-template/src/main.ts process.send [Function (anonymous)]
sending esm file:///Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js process.send [Function (anonymous)]
received {
  type: 'dependency',
  path: 'file:///Users/felix/code/node-ts-template/src/main.ts'
}
sending esm file:///Users/felix/code/node-ts-template/src/lib/logger.ts process.send [Function (anonymous)]
received {
  type: 'dependency',
  path: 'file:///Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js'
}
sending esm file:///Users/felix/code/node-ts-template/src/lib/config.ts process.send [Function (anonymous)]
received {
  type: 'dependency',
  path: 'file:///Users/felix/code/node-ts-template/src/lib/logger.ts'
}
received {
  type: 'dependency',
  path: 'file:///Users/felix/code/node-ts-template/src/lib/config.ts'
}
sending esm file:///Users/felix/code/node-ts-template/node_modules/pino/pino.js process.send [Function (anonymous)]
received {
  type: 'dependency',
  path: 'file:///Users/felix/code/node-ts-template/node_modules/pino/pino.js'
}
sending cjs /Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js process.send [Function (anonymous)]
received {
  type: 'dependency',
  path: '/Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js'
}

<...>

Node 20.5.0

> node-typescript-starter@0.0.0 dev
> tsx watch --clear-screen=false ./src/main.ts | pino-pretty

sending esm file:///Users/felix/code/node-ts-template/src/main.ts process.send undefined
sending esm file:///Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js process.send undefined
sending esm file:///Users/felix/code/node-ts-template/src/lib/logger.ts process.send undefined
sending esm file:///Users/felix/code/node-ts-template/src/lib/config.ts process.send undefined
sending esm file:///Users/felix/code/node-ts-template/node_modules/pino/pino.js process.send undefined
sending cjs /Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js process.send [Function (anonymous)]
sending cjs /Users/felix/code/node-ts-template/node_modules/pino/pino.js process.send [Function (anonymous)]
sending cjs /Users/felix/code/node-ts-template/node_modules/pino-std-serializers/index.js process.send [Function (anonymous)]
sending cjs /Users/felix/code/node-ts-template/node_modules/pino-std-serializers/lib/err.js process.send [Function (anonymous)]
received {
  type: 'dependency',
  path: '/Users/felix/code/node-ts-template/node_modules/dotenv/lib/main.js'
}
<...>

In this case, no esm module is ever received as process.send is not defined when the loader tries to send dependencies over IPC.

I looked for causes and found this change to the loader API that might be related.

In a github issue that discusses a seemingly similar case, it was suggested that globalPreload could be a workaround.

Hope this is helpful!

@privatenumber
Copy link
Owner

Wow thank you so much for the insightful investigation @fspoettel
I think we can work on a fix now

@npdev453
Copy link

npdev453 commented Aug 6, 2023

Wrote a fix esbuild-kit/esm-loader#64 based on @fspoettel research. Working well for me, but can somebody test it in him configurations also too?

@privatenumber, waiting for review.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working outdated watch
Projects
None yet
9 participants