Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/api/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ changes:
* `deregister()` {Function} Remove the registered hooks so that they are no
longer called. Hooks are otherwise retained for the lifetime of the running
process.
* `[Symbol.dispose]` {Function} The same as `deregister`.
Register [hooks][] that customize Node.js module resolution and loading behavior.
See [Customization hooks][]. The returned object can be used to
Expand Down
13 changes: 9 additions & 4 deletions lib/internal/modules/customization_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
StringPrototypeSlice,
StringPrototypeStartsWith,
Symbol,
SymbolDispose,
} = primordials;
const {
isAnyArrayBuffer,
Expand Down Expand Up @@ -83,10 +84,7 @@ class ModuleHooks {

ObjectFreeze(this);
}
// TODO(joyeecheung): we may want methods that allow disabling/enabling temporarily
// which just sets the item in the array to undefined temporarily.
// TODO(joyeecheung): this can be the [Symbol.dispose] implementation to pair with
// `using` when the explicit resource management proposal is shipped by V8.

/**
* Deregister the hook instance.
*/
Expand All @@ -101,6 +99,13 @@ class ModuleHooks {
ArrayPrototypeSplice(loadHooks, index, 1);
}
}

/**
* Deregister the hook instance.
*/
[SymbolDispose]() {
this.deregister();
}
};

/**
Expand Down
26 changes: 26 additions & 0 deletions test/module-hooks/test-module-hooks-dispose.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use strict';

const common = require('../common');
const assert = require('assert');
const { registerHooks } = require('module');

// Test that using syntax works.
{
// eslint-disable-next-line no-unused-vars
using hook = registerHooks({
load: common.mustCall((url, context, nextLoad) => {
const result = nextLoad(url, context);
assert.strictEqual(result.source, '');
return {
source: 'export const hello = "world"',
};
}),
});

const mod = require('../fixtures/empty.js');
assert.strictEqual(mod.hello, 'world');
}

delete require.cache[require.resolve('../fixtures/empty.js')];
const mod = require('../fixtures/empty.js');
assert.deepStrictEqual(mod, {});
Loading