Skip to content

Commit

Permalink
lib: move module exports proxy into a separate method
Browse files Browse the repository at this point in the history
Also added the comment in f074612 to make
NativeModule.prototype.compile() more readable.

PR-URL: #24057
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information
joyeecheung authored and targos committed Nov 6, 2018
1 parent 10156c6 commit 879c0f1
Showing 1 changed file with 59 additions and 51 deletions.
110 changes: 59 additions & 51 deletions lib/internal/bootstrap/loaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,64 @@
undefined;
};

// Provide named exports for all builtin libraries so that the libraries
// may be imported in a nicer way for esm users. The default export is left
// as the entire namespace (module.exports) and wrapped in a proxy such
// that APMs and other behavior are still left intact.
NativeModule.prototype.proxifyExports = function() {
this.exportKeys = ObjectKeys(this.exports);

const update = (property, value) => {
if (this.reflect !== undefined &&
ReflectApply(ObjectHasOwnProperty,
this.reflect.exports, [property]))
this.reflect.exports[property].set(value);
};

const handler = {
__proto__: null,
defineProperty: (target, prop, descriptor) => {
// Use `Object.defineProperty` instead of `Reflect.defineProperty`
// to throw the appropriate error if something goes wrong.
ObjectDefineProperty(target, prop, descriptor);
if (typeof descriptor.get === 'function' &&
!ReflectHas(handler, 'get')) {
handler.get = (target, prop, receiver) => {
const value = ReflectGet(target, prop, receiver);
if (ReflectApply(ObjectHasOwnProperty, target, [prop]))
update(prop, value);
return value;
};
}
update(prop, getOwn(target, prop));
return true;
},
deleteProperty: (target, prop) => {
if (ReflectDeleteProperty(target, prop)) {
update(prop, undefined);
return true;
}
return false;
},
set: (target, prop, value, receiver) => {
const descriptor = ReflectGetOwnPropertyDescriptor(target, prop);
if (ReflectSet(target, prop, value, receiver)) {
if (descriptor && typeof descriptor.set === 'function') {
for (const key of this.exportKeys) {
update(key, getOwn(target, key, receiver));
}
} else {
update(prop, getOwn(target, prop, receiver));
}
return true;
}
return false;
}
};

this.exports = new Proxy(this.exports, handler);
};

NativeModule.prototype.compile = function() {
const id = this.id;
let source = NativeModule.getSource(id);
Expand Down Expand Up @@ -299,57 +357,7 @@
fn(this.exports, requireFn, this, process, internalBinding);

if (config.experimentalModules && !NativeModule.isInternal(this.id)) {
this.exportKeys = ObjectKeys(this.exports);

const update = (property, value) => {
if (this.reflect !== undefined &&
ReflectApply(ObjectHasOwnProperty,
this.reflect.exports, [property]))
this.reflect.exports[property].set(value);
};

const handler = {
__proto__: null,
defineProperty: (target, prop, descriptor) => {
// Use `Object.defineProperty` instead of `Reflect.defineProperty`
// to throw the appropriate error if something goes wrong.
ObjectDefineProperty(target, prop, descriptor);
if (typeof descriptor.get === 'function' &&
!ReflectHas(handler, 'get')) {
handler.get = (target, prop, receiver) => {
const value = ReflectGet(target, prop, receiver);
if (ReflectApply(ObjectHasOwnProperty, target, [prop]))
update(prop, value);
return value;
};
}
update(prop, getOwn(target, prop));
return true;
},
deleteProperty: (target, prop) => {
if (ReflectDeleteProperty(target, prop)) {
update(prop, undefined);
return true;
}
return false;
},
set: (target, prop, value, receiver) => {
const descriptor = ReflectGetOwnPropertyDescriptor(target, prop);
if (ReflectSet(target, prop, value, receiver)) {
if (descriptor && typeof descriptor.set === 'function') {
for (const key of this.exportKeys) {
update(key, getOwn(target, key, receiver));
}
} else {
update(prop, getOwn(target, prop, receiver));
}
return true;
}
return false;
}
};

this.exports = new Proxy(this.exports, handler);
this.proxifyExports();
}

this.loaded = true;
Expand Down

0 comments on commit 879c0f1

Please sign in to comment.