@@ -235,9 +235,14 @@ changes:
235235* ` options` {Object}
236236 * ` load` {Function|undefined} See [load hook][]. **Default:** ` undefined` .
237237 * ` resolve` {Function|undefined} See [resolve hook][]. **Default:** ` undefined` .
238+ * Returns: {Object} An object with the following property:
239+ * ` deregister()` {Function} Remove the registered hooks so that they are no
240+ longer called. Hooks are otherwise retained for the lifetime of the running
241+ process.
238242
239243Register [hooks][] that customize Node.js module resolution and loading behavior.
240- See [Customization hooks][].
244+ See [Customization hooks][]. The returned object can be used to
245+ [deregister the hooks][deregistration of synchronous customization hooks].
241246
242247### ` module.stripTypeScriptTypes(code[, options])`
243248
@@ -800,6 +805,63 @@ hook to signal that the chain is intentionally ending at your hook.
800805If a hook should be applied when loading other hook modules, the other hook
801806modules should be loaded after the hook is registered.
802807
808+ #### Deregistration of synchronous customization hooks
809+
810+ The object returned by ` registerHooks ()` has a ` deregister ()` method that can be
811+ used to remove the hooks from the chain. Once ` deregister ()` is called, the hooks
812+ will no longer be invoked during module resolution or loading.
813+
814+ This is currently only available for synchronous hooks registered via ` registerHooks ()` , not for asynchronous
815+ hooks registered via ` module .register ()` .
816+
817+ ` ` ` mjs
818+ import { registerHooks } from ' node:module' ;
819+
820+ const hooks = registerHooks ({
821+ resolve (specifier , context , nextResolve ) {
822+ console .log (' resolve hook called for' , specifier);
823+ return nextResolve (specifier, context);
824+ },
825+ load (url , context , nextLoad ) {
826+ return nextLoad (url, context);
827+ },
828+ });
829+
830+ // At this point, the hooks are active and will be called for
831+ // any subsequent import() or require() calls.
832+ await import (' ./my-module.mjs' );
833+
834+ // Later, remove the hooks from the chain.
835+ hooks .deregister ();
836+
837+ // Subsequent loads will no longer trigger the hooks.
838+ await import (' ./another-module.mjs' );
839+ ` ` `
840+
841+ ` ` ` cjs
842+ const { registerHooks } = require (' node:module' );
843+
844+ const hooks = registerHooks ({
845+ resolve (specifier , context , nextResolve ) {
846+ console .log (' resolve hook called for' , specifier);
847+ return nextResolve (specifier, context);
848+ },
849+ load (url , context , nextLoad ) {
850+ return nextLoad (url, context);
851+ },
852+ });
853+
854+ // At this point, the hooks are active and will be called for
855+ // any subsequent require() calls.
856+ require (' ./my-module.cjs' );
857+
858+ // Later, remove the hooks from the chain.
859+ hooks .deregister ();
860+
861+ // Subsequent loads will no longer trigger the hooks.
862+ require (' ./another-module.cjs' );
863+ ` ` `
864+
803865#### Hook functions accepted by ` module .registerHooks ()`
804866
805867<!-- YAML
@@ -2031,6 +2093,7 @@ returned object contains the following keys:
20312093[asynchronous ` resolve` hook]: #asynchronous-resolvespecifier-context-nextresolve
20322094[asynchronous hook functions]: #asynchronous-hooks-accepted-by-moduleregister
20332095[caveats of asynchronous customization hooks]: #caveats-of-asynchronous-customization-hooks
2096+ [deregistration of synchronous customization hooks]: #deregistration-of-synchronous-customization-hooks
20342097[hooks]: #customization-hooks
20352098[load hook]: #synchronous-loadurl-context-nextload
20362099[module compile cache]: #module-compile-cache
0 commit comments