aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-08-31 16:20:26 -0700
committerGravatar Dylan Conway <dylan.conway567@gmail.com> 2023-08-31 16:20:26 -0700
commit4d944773f0234262e2df0dfd10cb564d3cdf6125 (patch)
treefae4fa727d20cce5aad74c7ac4d132075c8baa11
parentbd7262f037589a69be8b5fb2f705666309c32b86 (diff)
downloadbun-4d944773f0234262e2df0dfd10cb564d3cdf6125.tar.gz
bun-4d944773f0234262e2df0dfd10cb564d3cdf6125.tar.zst
bun-4d944773f0234262e2df0dfd10cb564d3cdf6125.zip
export non-enumerable values
-rw-r--r--src/bun.js/bindings/CommonJSModuleRecord.cpp14
-rw-r--r--test/bundler/bundler_cjs2esm.test.ts69
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",
+ },
+ });
});