Skip to content

module: addBuiltinLibsToObject refactoring #14085

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

Closed
wants to merge 1 commit into from
Closed
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
51 changes: 29 additions & 22 deletions lib/internal/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,43 +83,50 @@ const builtinLibs = [
'string_decoder', 'tls', 'tty', 'url', 'util', 'v8', 'vm', 'zlib'
];

// Make built-in modules available directly (loaded lazily).
function addBuiltinLibsToObject(object) {
// Make built-in modules available directly (loaded lazily).
builtinLibs.forEach((name) => {
const configurable = true;
const enumerable = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these are necessary. I would just keep these values inline to ensure no variable lookup has to be done by V8.


// Setter function that will be bound to some lib name
function setReal(libname, value) {
// Deleting the property before re-assigning it disables the
// getter/setter mechanism.
delete object[libname];
object[libname] = value;
}

for (var n = 0, len = builtinLibs.length; n < len; n++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to cache the length, V8 can work fine with using .length in the conditional part.

// Goals of this mechanism are:
// - Lazy loading of built-in modules
// - Having all built-in modules available as non-enumerable properties
// - Allowing the user to re-assign these variables as if there were no
// pre-existing globals with the same name.
const libname = builtinLibs[n];
const set = setReal.bind(null, libname);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why bind() this method but not the getter? I think we should be consistent. I do not know offhand if either method is more efficient, but since there are not so many built-in modules it may not make much difference.


const setReal = (val) => {
// Deleting the property before re-assigning it disables the
// getter/setter mechanism.
delete object[name];
object[name] = val;
};

Object.defineProperty(object, name, {
Object.defineProperty(object, libname, {
get: () => {
const lib = require(name);
const lib = require(libname);

// Disable the current getter/setter and set up a new
// non-enumerable property.
delete object[name];
Object.defineProperty(object, name, {
// Disable the current getter/setter
delete object[libname];

// Set up a new non-emumerable propery
Object.defineProperty(object, libname, {
get: () => lib,
set: setReal,
configurable: true,
enumerable: false
set,
configurable,
enumerable
});

return lib;
},
set: setReal,
configurable: true,
enumerable: false
set,
configurable,
enumerable
});
});
}
}

module.exports = exports = {
Expand Down