diff options
author | 2023-08-31 16:20:26 -0700 | |
---|---|---|
committer | 2023-08-31 16:20:26 -0700 | |
commit | 4d944773f0234262e2df0dfd10cb564d3cdf6125 (patch) | |
tree | fae4fa727d20cce5aad74c7ac4d132075c8baa11 | |
parent | bd7262f037589a69be8b5fb2f705666309c32b86 (diff) | |
download | bun-4d944773f0234262e2df0dfd10cb564d3cdf6125.tar.gz bun-4d944773f0234262e2df0dfd10cb564d3cdf6125.tar.zst bun-4d944773f0234262e2df0dfd10cb564d3cdf6125.zip |
export non-enumerable values
-rw-r--r-- | src/bun.js/bindings/CommonJSModuleRecord.cpp | 14 | ||||
-rw-r--r-- | test/bundler/bundler_cjs2esm.test.ts | 69 |
2 files changed, 79 insertions, 4 deletions
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp index a1f5781d7..007410dde 100644 --- a/src/bun.js/bindings/CommonJSModuleRecord.cpp +++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp @@ -556,7 +556,7 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject, if (canPerformFastEnumeration(structure)) { exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool { auto key = entry.key(); - if (key->isSymbol() || entry.attributes() & PropertyAttribute::DontEnum || key == esModuleMarker) + if (key->isSymbol() || entry.attributes() & PropertyAttribute::Accessor || entry.attributes() & PropertyAttribute::CustomAccessor || key == esModuleMarker) return true; needsToAssignDefault = needsToAssignDefault && key != vm.propertyNames->defaultKeyword; @@ -568,7 +568,7 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject, }); } else { JSC::PropertyNameArray properties(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude); - exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Exclude); + exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Include); if (catchScope.exception()) { catchScope.clearExceptionExceptTermination(); return; @@ -586,6 +586,9 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject, if (!exports->getPropertySlot(globalObject, property, slot)) continue; + if (slot.isAccessor() || slot.isUnset()) + continue; + exportNames.append(property); JSValue getterResult = slot.getValue(globalObject, property); @@ -606,7 +609,7 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject, } else if (canPerformFastEnumeration(structure)) { exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool { auto key = entry.key(); - if (key->isSymbol() || entry.attributes() & PropertyAttribute::DontEnum || key == vm.propertyNames->defaultKeyword) + if (key->isSymbol() || key == vm.propertyNames->defaultKeyword || entry.attributes() & PropertyAttribute::Accessor || entry.attributes() & PropertyAttribute::CustomAccessor) return true; JSValue value = exports->getDirect(entry.offset()); @@ -617,7 +620,7 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject, }); } else { JSC::PropertyNameArray properties(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude); - exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Exclude); + exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Include); if (catchScope.exception()) { catchScope.clearExceptionExceptTermination(); return; @@ -635,6 +638,9 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject, if (!exports->getPropertySlot(globalObject, property, slot)) continue; + if (slot.isAccessor() || slot.isUnset()) + continue; + exportNames.append(property); JSValue getterResult = slot.getValue(globalObject, property); diff --git a/test/bundler/bundler_cjs2esm.test.ts b/test/bundler/bundler_cjs2esm.test.ts index 01a17356b..5d8694b33 100644 --- a/test/bundler/bundler_cjs2esm.test.ts +++ b/test/bundler/bundler_cjs2esm.test.ts @@ -286,4 +286,73 @@ describe("bundler", () => { stdout: "react\nreact\nreact\nreact\nundefined\nreact\nreact\nreact\nreact\nreact\nreact\n1 react\nreact\nreact", }, }); + for (const bundling of [true, false]) { + itBundled("cjs2esm/NonEnumerableModuleExports", { + files: { + "/entry.js": /* js */ ` + import { foo } from "./foo.cjs"; + import { bar } from "./bar.cjs"; + console.log(foo, bar); + `, + "/foo.cjs": /* js */ ` + Object.defineProperty(exports, "foo", { + enumerable: false, + value: 1, + }); + `, + "/bar.cjs": /* js */ ` + Object.defineProperty(exports, "__esModule", { + value: true, + }); + Object.defineProperty(exports, "bar", { + enumerable: false, + value: 1 + }) + `, + }, + bundling, + run: { + stdout: "1 1", + }, + }); + } + itBundled("cjs2esm/NonEnumerableModuleExportsAccessors", { + files: { + "/entry.js": /* js */ ` + import { foo } from "./foo.cjs"; + console.log(foo); + `, + "/foo.cjs": /* js */ ` + Object.defineProperty(exports, "foo", { + enumerable: false, + get: () => 1, + }); + `, + }, + bundling: false, + run: { + error: "SyntaxError: Import named 'foo' not found in module", + }, + }); + itBundled("cjs2esm/NonEnumerableModuleExportsAccessors2", { + files: { + "/entry.js": /* js */ ` + import { foo } from "./foo.cjs"; + console.log(foo); + `, + "/foo.cjs": /* js */ ` + Object.defineProperty(exports, "__esModule", { + value: true, + }); + Object.defineProperty(exports, "foo", { + enumerable: false, + get: () => 1, + }); + `, + }, + bundling: false, + run: { + error: "SyntaxError: Import named 'foo' not found in module", + }, + }); }); |