diff --git a/doc/api/module.md b/doc/api/module.md index 81e49882def0bf..fc1a375b54c6de 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -235,9 +235,14 @@ changes: * `options` {Object} * `load` {Function|undefined} See [load hook][]. **Default:** `undefined`. * `resolve` {Function|undefined} See [resolve hook][]. **Default:** `undefined`. +* Returns: {Object} An object with the following property: + * `deregister()` {Function} Remove the registered hooks so that they are no + longer called. Hooks are otherwise retained for the lifetime of the running + process. Register [hooks][] that customize Node.js module resolution and loading behavior. -See [Customization hooks][]. +See [Customization hooks][]. The returned object can be used to +[deregister the hooks][deregistration of synchronous customization hooks]. ### `module.stripTypeScriptTypes(code[, options])` @@ -800,6 +805,63 @@ hook to signal that the chain is intentionally ending at your hook. If a hook should be applied when loading other hook modules, the other hook modules should be loaded after the hook is registered. +#### Deregistration of synchronous customization hooks + +The object returned by `registerHooks()` has a `deregister()` method that can be +used to remove the hooks from the chain. Once `deregister()` is called, the hooks +will no longer be invoked during module resolution or loading. + +This is currently only available for synchronous hooks registered via `registerHooks()`, not for asynchronous +hooks registered via `module.register()`. + +```mjs +import { registerHooks } from 'node:module'; + +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + console.log('resolve hook called for', specifier); + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + return nextLoad(url, context); + }, +}); + +// At this point, the hooks are active and will be called for +// any subsequent import() or require() calls. +await import('./my-module.mjs'); + +// Later, remove the hooks from the chain. +hooks.deregister(); + +// Subsequent loads will no longer trigger the hooks. +await import('./another-module.mjs'); +``` + +```cjs +const { registerHooks } = require('node:module'); + +const hooks = registerHooks({ + resolve(specifier, context, nextResolve) { + console.log('resolve hook called for', specifier); + return nextResolve(specifier, context); + }, + load(url, context, nextLoad) { + return nextLoad(url, context); + }, +}); + +// At this point, the hooks are active and will be called for +// any subsequent require() calls. +require('./my-module.cjs'); + +// Later, remove the hooks from the chain. +hooks.deregister(); + +// Subsequent loads will no longer trigger the hooks. +require('./another-module.cjs'); +``` + #### Hook functions accepted by `module.registerHooks()`