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

nodemon (or similar) in core #40429

Closed
bnb opened this issue Oct 12, 2021 · 46 comments · Fixed by #44366
Closed

nodemon (or similar) in core #40429

bnb opened this issue Oct 12, 2021 · 46 comments · Fixed by #44366
Labels
feature request Issues that request new features to be added to Node.js.

Comments

@bnb
Copy link
Contributor

bnb commented Oct 12, 2021

Is your feature request related to a problem? Please describe.
Not particularly. It's related to a problem in that it is proposing the addition or inclusion of a tool that is widely used for a common problem.

Describe the solution you'd like

I recently put out a tweet from @nodejs on Twitter asking folks what tool they find most useful day-to-day. I generally try to do this not with the intent to bring a proposal or something like that, but to have some engaging activity that could be helpful to someone somewhere.

One thing I noticed was just how many people replied with "nodemon". It seemed to come up just as often as DevTools, VS Code, and TypeScript which I found remarkable.

I'd like to recommend that we consider either vendoring nodemon or explore writing a nodemon-like from scratch in core.

Describe alternatives you've considered
Doing nothing, which would be fine. This is a problem that is obviously solvable in userland, but one that people clearly need solved. If the result of this issue is "this should be in userland" that's totally fine.

@Mesteery Mesteery added the feature request Issues that request new features to be added to Node.js. label Oct 12, 2021
@capaj
Copy link

capaj commented Oct 12, 2021

I very much prefer https://github.com/fgnass/node-dev to nodemon mostly because nodemon restarts the whole process when it detects a change, whereas node-dev only reloads the single module which changed and it's dependents. On bigger projects this can save quite a lot of overhead.

@boneskull
Copy link
Contributor

@capaj that's a different use case

@capaj
Copy link

capaj commented Oct 12, 2021

@boneskull why do you think it's a different usecase? I use it on typical backend projects interchangeably.

@boneskull
Copy link
Contributor

it appears to be for development. but regardless, this issue is about nodemon, which many people use

@capaj
Copy link

capaj commented Oct 12, 2021

Are you talking about using nodemon as a tool to restart your server in production?

FYI most people use nodemon just for development. A very tiny minority of users use nodemon for other usecases.
Also this issue is not about nodemon specifically. I understand it as a feature request for a tool to manage code reload for development of long running node.js processes.
I think the author only mentioned nodemon because that is the most commonly used tool for this.

@bmeck
Copy link
Member

bmeck commented Oct 12, 2021

I would like to start that we should look at solving the major use cases, not all possible edge cases with this. I do want this feature very badly.

  1. This would be ideal to enable the reload devtools workflows that are missing from node's devtools integration.
  2. This could enable various sane things like file watching causing restarts during development. Though, this could have some loss of data if done too pro-actively so likely needs some kind of config around how to do restarts.
  3. This could enable a sane path towards supporting import.meta.hot which isn't possible due to ESM cache having no way to safely eject entries in certain scenarios (effect of the ESM spec design).
  4. For "production" I think there are plenty of people using restart managers (nodemon or other) and any restart feature could be used for this purpose to avoid some problems in particular with people wanting to setup Windows Services that restart on exit (staring blankly at my minecraft server in the corner here).

I think determining what restart means (soft vs hard) would be a good first step to figuring out what could be in core. I think if we do want devtools integration that relies on reloads like perf tab to properly work we likely won't be able to just vendor in an existing library though. Also, node can likely spin up a much smaller footprint manager than a full blown JS VM.

I don't think bickering about gritty details and if something is the best solution needs to be done at the investigation phase of this. I think there will generally be more specialized solutions that people can use if whatever node ships doesn't fit their specific need. We are trying to help users and if we don't ship anything due to bickering, we don't improve the situation for anyone.

@mscdex
Copy link
Contributor

mscdex commented Oct 12, 2021

I think there will generally be more specialized solutions that people can use if whatever node ships doesn't fit their specific need.

This feature request seems like one of those things that can be very opinionated, which makes me lean towards -1 for inclusion in node core. However, I suppose at the very least if it's possible to build/install node without whatever tool, I would be more ok with it. I already use (other) 3rd party tools for managing node processes and don't want to add more bloat to my node installations.

@bmeck
Copy link
Member

bmeck commented Oct 13, 2021

@mscdex I'm not sure preventing every kilobyte of unused core is really a goal of Node. Providing use cases to users is paramount and various things like existing devtools workflows that are currently disabled in the node inspector need some kind of internal reload manager. We for example ship acorn which is not used outside of the REPL. We also have websockets implementation for the inspector but never expose it either. Fighting to avoid adding any features that won't be used in all cases is tantamount to ripping out most of core so node is not usable on its own and all features must be bespoke and from the ecosystem.

@mscdex
Copy link
Contributor

mscdex commented Oct 13, 2021

We for example ship acorn which is not used outside of the REPL. We also have websockets implementation for the inspector but never expose it either.

We don't already include nodemon, so these examples aren't quite the same. Besides, as far as I understand it, in the case of acorn and websockets both were more or less required. nodemon is not required to fix an issue or compatibility problem that currently exists in node core itself.

Fighting to avoid adding any features that won't be used in all cases is tantamount to ripping out most of core so node is not usable on its own and all features must be bespoke and from the ecosystem.

That's a bit extreme. We've already had this small core discussion many times in the past, so I'm not going to repeat it here. However, I don't think there is anything wrong with wanting a small(er) node core (not just in literal size but also in scope) and not wanting to throw in the kitchen sink.

@mcollina
Copy link
Member

I tend to agree we need something to solve this problem. I don't think we should be embedding nodemon - that's a solved problem at this point, I don't think we would stop people from using nodemon. I would like something better than nodemon.

However the hot reloading within devtools and import.meta.hot are important and currently impossible for us to solve for ESM.

@capaj
Copy link

capaj commented Oct 13, 2021

impossible for us to solve for ESM

due to some limitations in the current node ESM loader implementation?

@mcollina
Copy link
Member

due to some limitations in the current node ESM loader implementation?

As far as I know it's currently impossible to implement hot module reloading in ESM.

@bnb
Copy link
Contributor Author

bnb commented Oct 13, 2021

However the hot reloading within devtools and import.meta.hot are important and currently impossible for us to solve for ESM.

@mcollina is your assertion that a --watch feature might solve this, in line with what @bmeck mentioned, or that --watch also won't solve this? Just want to be sure.

@bmeck
Copy link
Member

bmeck commented Oct 13, 2021

due to some limitations in the current node ESM loader implementation?

No. This is due to how caching is constrained by the specification, once a URL is used it is permanently cached and cannot be unloaded.

Besides, as far as I understand it, in the case of acorn and websockets both were more or less required.

In both cases there is no requirement that node support users wishing to use the features these provide.

@bmeck
Copy link
Member

bmeck commented Oct 13, 2021

@bnb a watch mechanism could automatically propagate an import.meta.hot signal for reloading yes.

@mcollina
Copy link
Member

@bnb what @bmeck and I are saying is that it's not possible to do hot reloading right now with ESM.

@bmeck
Copy link
Member

bmeck commented Oct 13, 2021

Well, you can reload... but it leaks memory and under the hood rewrites URLs (would still be true with any sort of --watch), we have a PR with a test to show that mocking/aliasing a URL works but the only way to not leak is to have some sort of manager like reloading and an opt-out mechanism like import.meta.hot to avoid unnecessary reloading.

@bnb
Copy link
Contributor Author

bnb commented Feb 1, 2022

ping on this.

@targos
Copy link
Member

targos commented Feb 1, 2022

@bnb what's the next step?

@bnb
Copy link
Contributor Author

bnb commented Feb 1, 2022

my understanding of next steps:

it (generally) seems like there's agreement that we'd like to see something along these lines. defining the scope of what that is and isn't, including the feedback from @mcollina and @bmeck, would be helpful in guiding an actual eventual implementation.

@bmeck
Copy link
Member

bmeck commented Feb 1, 2022 via email

@mcollina
Copy link
Member

mcollina commented Feb 1, 2022

@bnb a preliminary step is to embed https://www.npmjs.com/package/fsevents in core to replace the buggy fs watch logic we have for macs (might be a new API). There might be another issue around this somewhere.

I'm happy to join a call to scope this.

@targos
Copy link
Member

targos commented Feb 1, 2022

@mcollina the documentation says that we use fsevents on mac: https://nodejs.org/dist/latest-v17.x/docs/api/fs.html#availability

What is buggy about what we do? Is there an issue about it?

@mcollina
Copy link
Member

mcollina commented Feb 2, 2022

I don't know, maybe @pipobscure can help clarify.

@pipobscure
Copy link
Contributor

The latest libuv does use fsevents under the hood these days. This was an effort undertaken by libuv a while back after chatting about moving fsevents into node core at a conference (again quite a while back).

This wasn’t always the case. Originally libuv was using posix stuff for monitoring files and would quickly run into ulimit for file handle if monitoring deep directories (one handle per directory/file).

So for tools like nodemon I’d recommend moving to the builtin fs watch capabilities as they should be sufficient.

Fsevents offers more granularity and more history, so it’s still useful though for a much smaller number of cases. It’s the underlying technology for time machine, so you can actually go back in time (before process start) and recall events as well. Which is great, but not all that useful for something like nodemon.

So from my perspective there’s nothing that would prevent just using the builtin stuff here. That being said, I have not tried out the fsevents implementation if libuv, so it may be worth doing an experiment. But if something doesn’t work quite right I’d think the place to fix it is in libuv.

@mcollina
Copy link
Member

mcollina commented Feb 3, 2022

Thanks @pipobscure for the explanation!

@github-actions
Copy link
Contributor

github-actions bot commented Aug 3, 2022

There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment.

For more information on how the project manages feature requests, please consult the feature request management document.

@MoLow
Copy link
Member

MoLow commented Aug 18, 2022

Could you elaborate on that point?

  1. my assumption, (it might be wrong) is that using sub-processes has a bigger performance penalty than using a thread for handling file system events.
  2. using sub-processes can introduce some edge cases that need to be handled, for example, what happens when the sub-process is killed using the OS?
  3. some features depending on a single process/pid are now a little bit more confusing and hard to use (e.g SIGUSR1, spawn with bot --watch and ipc)

if we use sub-processes we might as well vendor nodemon

@privatenumber
Copy link
Contributor

We also have a watcher in tsx, which works similarly to node-dev as it only watches the dependency tree (but also supports native ESM).

It also spawns a child process which has been working great. No noticeable performance drawbacks and I think the implementation is minimal & maintainable.


Another file watcher alternative to consider is @parcel/watcher, which leverages FSEvents/Watchman/inotify/etc.

Apparently it was built to address the unreliability of chokidar and is now even used by VSCode.

@remy
Copy link

remy commented Sep 5, 2022

@MoLow nice. Now wondering if nodemon just got it's death sentence 😆 😢

@mcollina
Copy link
Member

mcollina commented Sep 5, 2022

@remy I don't think so. First, this has a long way to go before reaching feature parity (i.e. https://github.com/remy/nodemon/blob/HEAD/doc/requireable.md is missing). Second, this is hardly stable, and it will require a few years before it is rolled out to all Node.js versions. Third, everybody using your software would hardly switch.

@remy
Copy link

remy commented Sep 5, 2022

:D yeah, the old dogs and new tricks thing will probably keep folks using nodemon for many a year.

Good addition to node either way 👍

RafaelGSS pushed a commit that referenced this issue Sep 5, 2022
PR-URL: #44366
Fixes: #40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Sep 7, 2022
PR-URL: nodejs#44366
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Sep 8, 2022
PR-URL: nodejs#44366
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
(cherry picked from commit beb0520)
MoLow added a commit to MoLow/node that referenced this issue Sep 8, 2022
PR-URL: nodejs#44366
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Sep 15, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44571
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Fyko pushed a commit to Fyko/node that referenced this issue Sep 15, 2022
PR-URL: nodejs#44366
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
RafaelGSS pushed a commit that referenced this issue Sep 23, 2022
PR-URL: #44366
Backport-PR-URL: #44571
Fixes: #40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Rafael Gonzaga <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
RafaelGSS pushed a commit that referenced this issue Sep 26, 2022
PR-URL: #44366
Backport-PR-URL: #44571
Fixes: #40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Rafael Gonzaga <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Sep 29, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44814
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Sep 29, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44815
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
danielleadams pushed a commit that referenced this issue Oct 2, 2022
PR-URL: #44366
Backport-PR-URL: #44815
Fixes: #40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Oct 3, 2022
PR-URL: nodejs#44366
Backport-PR-URL: https://github.com/nodejs/node/pull/TBD
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Oct 3, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44877
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Oct 12, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44877
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Oct 12, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44976
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Oct 12, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44976
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
MoLow added a commit to MoLow/node that referenced this issue Oct 12, 2022
PR-URL: nodejs#44366
Backport-PR-URL: nodejs#44976
Fixes: nodejs#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
@targos targos moved this from Todo to Done in Node.js feature requests Oct 22, 2022
richardlau pushed a commit that referenced this issue Nov 23, 2022
PR-URL: #44366
Backport-PR-URL: #44976
Fixes: #40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
guangwong pushed a commit to noslate-project/node that referenced this issue Jan 3, 2023
PR-URL: nodejs/node#44366
Backport-PR-URL: nodejs/node#44976
Fixes: nodejs/node#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
guangwong pushed a commit to noslate-project/node that referenced this issue Jan 3, 2023
PR-URL: nodejs/node#44366
Backport-PR-URL: nodejs/node#44976
Fixes: nodejs/node#40429
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Issues that request new features to be added to Node.js.
Projects
None yet
Development

Successfully merging a pull request may close this issue.