summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBradley Farias <bfarias@godaddy.com>2019-09-27 12:12:18 -0500
committerGuy Bedford <guybedford@gmail.com>2019-10-05 20:11:15 -0400
commit0b495a899bdf9a26b25a6e31177512531c841e0e (patch)
treed0c3a6b3768c0882ddf2eae1a01df419b50bb38f /lib
parente1e2f669f65fd53323b8a58d80ed3cee039706b7 (diff)
downloadandroid-node-v8-0b495a899bdf9a26b25a6e31177512531c841e0e.tar.gz
android-node-v8-0b495a899bdf9a26b25a6e31177512531c841e0e.tar.bz2
android-node-v8-0b495a899bdf9a26b25a6e31177512531c841e0e.zip
esm: remove proxy for builtin exports
PR-URL: https://github.com/nodejs/node/pull/29737 Reviewed-By: Guy Bedford <guybedford@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Jan Krems <jan.krems@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Minwoo Jung <minwoo@nodesource.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/bootstrap/loaders.js92
-rw-r--r--lib/internal/modules/cjs/loader.js8
-rw-r--r--lib/internal/modules/esm/translators.js10
3 files changed, 47 insertions, 63 deletions
diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js
index cc1157a557..dbc21a9697 100644
--- a/lib/internal/bootstrap/loaders.js
+++ b/lib/internal/bootstrap/loaders.js
@@ -151,6 +151,7 @@ function NativeModule(id) {
this.id = id;
this.exports = {};
this.reflect = undefined;
+ this.esmFacade = undefined;
this.exportKeys = undefined;
this.loaded = false;
this.loading = false;
@@ -211,15 +212,19 @@ function requireWithFallbackInDeps(request) {
}
// This is exposed for public loaders
-NativeModule.prototype.compileForPublicLoader = function(needToProxify) {
+NativeModule.prototype.compileForPublicLoader = function(needToSyncExports) {
if (!this.canBeRequiredByUsers) {
// No code because this is an assertion against bugs
// eslint-disable-next-line no-restricted-syntax
throw new Error(`Should not compile ${this.id} for public use`);
}
this.compile();
- if (needToProxify && !this.exportKeys) {
- this.proxifyExports();
+ if (needToSyncExports) {
+ if (!this.exportKeys) {
+ this.exportKeys = Object.keys(this.exports);
+ }
+ this.getESMFacade();
+ this.syncExports();
}
return this.exports;
};
@@ -230,61 +235,38 @@ const getOwn = (target, property, receiver) => {
undefined;
};
+NativeModule.prototype.getURL = function() {
+ return `node:${this.id}`;
+};
+
+NativeModule.prototype.getESMFacade = function() {
+ if (this.esmFacade) return this.esmFacade;
+ const createDynamicModule = nativeModuleRequire(
+ 'internal/modules/esm/create_dynamic_module');
+ const url = this.getURL();
+ return this.esmFacade = createDynamicModule(
+ [], [...this.exportKeys, 'default'], url, (reflect) => {
+ this.reflect = reflect;
+ this.syncExports();
+ reflect.exports.default.set(this.exports);
+ });
+};
+
// 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 = Object.keys(this.exports);
-
- const update = (property, value) => {
- if (this.reflect !== undefined &&
- ObjectPrototype.hasOwnProperty(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.
- Object.defineProperty(target, prop, descriptor);
- if (typeof descriptor.get === 'function' &&
- !Reflect.has(handler, 'get')) {
- handler.get = (target, prop, receiver) => {
- const value = Reflect.get(target, prop, receiver);
- if (ObjectPrototype.hasOwnProperty(target, prop))
- update(prop, value);
- return value;
- };
- }
- update(prop, getOwn(target, prop));
- return true;
- },
- deleteProperty: (target, prop) => {
- if (Reflect.deleteProperty(target, prop)) {
- update(prop, undefined);
- return true;
- }
- return false;
- },
- set: (target, prop, value, receiver) => {
- const descriptor = Reflect.getOwnPropertyDescriptor(target, prop);
- if (Reflect.set(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;
+// as the entire namespace (module.exports) and updates when this function is
+// called so that APMs and other behavior are supported.
+NativeModule.prototype.syncExports = function() {
+ const names = this.exportKeys;
+ if (this.reflect) {
+ for (let i = 0; i < names.length; i++) {
+ const exportName = names[i];
+ if (exportName === 'default') continue;
+ this.reflect.exports[exportName].set(
+ getOwn(this.exports, exportName, this.exports)
+ );
}
- };
-
- this.exports = new Proxy(this.exports, handler);
+ }
};
NativeModule.prototype.compile = function() {
diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js
index 9bee9130d2..862b149e5a 100644
--- a/lib/internal/modules/cjs/loader.js
+++ b/lib/internal/modules/cjs/loader.js
@@ -1135,6 +1135,14 @@ Module._preloadModules = function(requests) {
parent.require(requests[n]);
};
+Module.syncBuiltinESMExports = function syncBuiltinESMExports() {
+ for (const mod of NativeModule.map.values()) {
+ if (mod.canBeRequiredByUsers) {
+ mod.syncExports();
+ }
+ }
+};
+
// Backwards compatibility
Module.Module = Module;
diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js
index 056bf64bf5..e8eddcfd21 100644
--- a/lib/internal/modules/esm/translators.js
+++ b/lib/internal/modules/esm/translators.js
@@ -128,14 +128,8 @@ translators.set('builtin', async function builtinStrategy(url) {
if (!module) {
throw new ERR_UNKNOWN_BUILTIN_MODULE(id);
}
- return createDynamicModule(
- [], [...module.exportKeys, 'default'], url, (reflect) => {
- debug(`Loading BuiltinModule ${url}`);
- module.reflect = reflect;
- for (const key of module.exportKeys)
- reflect.exports[key].set(module.exports[key]);
- reflect.exports.default.set(module.exports);
- });
+ debug(`Loading BuiltinModule ${url}`);
+ return module.getESMFacade();
});
// Strategy for loading a JSON file