Skip to content

esm: add `deregister` method

TBD

  • refactor hooks internals – remove chains in favor of loaderInstances; there is a tiny performance penalty when going through any given chain (since there's a conditional branch now and possibly extra iterations up to the total number of loaders) but i think this is negligible compared to the usability increase – there is now a default loader called default_loader that is registered like any other as node's internal one and only one array instead of several. the logic for adding/removing loaders is significantly simpler now.
  • change the return type of register – previously it returned whatever initialize did. @aduh95 noted that we should return a "loader handle" or a symbol to the loader instead of the initialize result which is what i've done here. i managed to make returning a symbol work across the thread gap. i am not 100% sold on symbol vs some kind of loader object which was also suggested (a thing that had a deregister method); i am still concerned about loader authors being able to pass initialization data back if it's somehow useful to them. N.B. this seems kind of like an 11th hour change now that 20.6.0 is imminent and the loaders API is being marked somewhat stable.
  • allow hook methods to receive a fourth state argument – so instead of returning the result of initialize and discard it, we now keep the result attached to the loader instance. this value is then fed back to hook invocations. after thinking about the comments in https://github.com/nodejs/loaders/issues/147 this actually seems necessary if there can be an arbitrary number of "copies" of any given loader; how can loaders differentiate their internal state from one another? there isn't a good way without something like this.
  • add deregister – this builds on the first two changes; the first one makes it sensible/trivial to remove existing loaders, and the second makes it possible for the user to actually be able to reference an individual loader which is necessary for removal

Suggestion from @GeoffreyBooth.

Adds deregister method on node:module that looks like this:

type Deregister = (id: string) => boolean;

Modifies the initialize hook to look like this:

type Initialize = (data: any, meta: {id: opaque}) => Promise<any>;

Internally registered instances of hooks are now tracked. This is so they can be removed later. The id of the registered instance is now passed to the initialize hook which can then be passed back to the caller of register.

// Loader
export const initialize = (_data, meta) => {
  return meta.id;
}
// Caller
import {register, deregister} from "node:module";

const id = register(...);

// ...

deregister(id);

Merge request reports

Loading