aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-05-29 21:01:39 -0700
committerGravatar GitHub <noreply@github.com> 2023-05-29 21:01:39 -0700
commit052df7d48c4b4c0e82810bf49a136d644883d3b5 (patch)
treeb3eb3ebd5a86dccb42fc72d0c3b87fcddd3e44ed
parent5990a9528f12be86cf95f4b46a3ecfa14f8ea97a (diff)
downloadbun-052df7d48c4b4c0e82810bf49a136d644883d3b5.tar.gz
bun-052df7d48c4b4c0e82810bf49a136d644883d3b5.tar.zst
bun-052df7d48c4b4c0e82810bf49a136d644883d3b5.zip
Cleanup CommonJS changes (#3112)bun-v0.6.5
* Add more GC in test * Fix handling of functions and re-assignments in CommonJS * Increase timeout --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
-rw-r--r--src/bun.js/bindings/CommonJSModuleRecord.cpp263
-rw-r--r--src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h1
-rw-r--r--src/bun.js/bindings/webcore/DOMIsoSubspaces.h2
-rw-r--r--src/bun.js/builtins/BunBuiltinNames.h1
-rw-r--r--src/bun.js/builtins/WebCoreJSBuiltins.cpp8
-rw-r--r--src/bun.js/builtins/ts/ImportMetaObject.ts11
-rw-r--r--src/bundler/bundle_v2.zig1
-rw-r--r--test/cli/run/require-cache-fixture.cjs9
-rw-r--r--test/js/bun/websocket/websocket-server.test.ts2
9 files changed, 248 insertions, 50 deletions
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp
index c77027983..8b4fdf60a 100644
--- a/src/bun.js/bindings/CommonJSModuleRecord.cpp
+++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp
@@ -1,3 +1,38 @@
+/**
+ * How this works
+ *
+ * CommonJS modules are transpiled by Bun's transpiler to the following:
+ *
+ * (function (exports, require, module) { ... code })(exports, require, module)
+ *
+ * Then, at runtime, we create a JSCommonJSModule object.
+ *
+ * On this special object, we override the setter for the "exports" property in
+ * a non-observable way (`static bool put ...`)
+ *
+ * When the setter is called, we set the internal "exports" property to the
+ * value passed in and we also update the requireMap with the new value.
+ *
+ * After the CommonJS module is executed, we:
+ * - Store the exports value in the requireMap (again)
+ * - Loop through the keys of the exports object and re-export as ES Module
+ * named exports
+ *
+ * If an exception occurs, we remove the entry from the requireMap.
+ *
+ * We tried using a CustomGetterSetter instead of overriding `put`, but it led
+ * to returning the getter itself
+ *
+ * How cyclical dependencies are handled
+ *
+ * Before executing the CommonJS module, we set the exports object in the
+ * requireMap to an empty object. When the CommonJS module is required again, we
+ * return the exports object from the requireMap. The values should be in sync
+ * while the module is being executed, unless module.exports is re-assigned to a
+ * different value. In that case, it will have a stale value.
+ *
+ */
+
#include "root.h"
#include "headers-handwritten.h"
#include "ZigGlobalObject.h"
@@ -31,13 +66,136 @@
namespace Bun {
using namespace JSC;
-JSC::Structure* createCommonJSModuleStructure(
+static Structure* internalCreateCommonJSModuleStructure(
+ Zig::GlobalObject* globalObject);
+
+class JSCommonJSModule final : public JSC::JSNonFinalObject {
+public:
+ using Base = JSC::JSNonFinalObject;
+ static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesPut;
+
+ mutable JSC::WriteBarrier<JSC::Unknown> m_exportsObject;
+ mutable JSC::WriteBarrier<JSC::JSString> m_id;
+
+ void finishCreation(JSC::VM& vm, JSC::JSValue exportsObject, JSC::JSString* id)
+ {
+ Base::finishCreation(vm);
+ ASSERT(inherits(vm, info()));
+ m_exportsObject.set(vm, this, exportsObject);
+ m_id.set(vm, this, id);
+
+ this->putDirectOffset(
+ vm,
+ 0,
+ exportsObject);
+
+ this->putDirectOffset(
+ vm,
+ 1,
+ id);
+
+ this->putDirectOffset(
+ vm,
+ 2,
+ id);
+ }
+
+ static JSCommonJSModule* create(
+ JSC::VM& vm,
+ JSC::Structure* structure,
+ JSC::JSValue exportsObject,
+ JSC::JSString* id)
+ {
+ JSCommonJSModule* cell = new (NotNull, JSC::allocateCell<JSCommonJSModule>(vm)) JSCommonJSModule(vm, structure);
+ cell->finishCreation(vm, exportsObject, id);
+ return cell;
+ }
+
+ JSValue exportsObject()
+ {
+ return m_exportsObject.get();
+ }
+
+ JSValue id()
+ {
+ return m_id.get();
+ }
+
+ DECLARE_VISIT_CHILDREN;
+
+ static bool put(
+ JSC::JSCell* cell,
+ JSC::JSGlobalObject* globalObject,
+ JSC::PropertyName propertyName,
+ JSC::JSValue value,
+ JSC::PutPropertySlot& slot)
+ {
+ JSCommonJSModule* thisObject = jsCast<JSCommonJSModule*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ auto& vm = globalObject->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+ auto* clientData = WebCore::clientData(vm);
+ bool result = Base::put(thisObject, globalObject, propertyName, value, slot);
+ if (result) {
+ // Whenever you call module.exports = ... in a module, we need to:
+ //
+ // - Update the internal exports object
+ // - Update the require map
+ //
+ if (propertyName == clientData->builtinNames().exportsPublicName()) {
+ thisObject->m_exportsObject.set(vm, thisObject, value);
+ Zig::GlobalObject* zigGlobalObject = jsCast<Zig::GlobalObject*>(globalObject);
+ zigGlobalObject->requireMap()->set(globalObject, thisObject->id(), value);
+ RETURN_IF_EXCEPTION(throwScope, false);
+ }
+ }
+
+ RELEASE_AND_RETURN(throwScope, result);
+ }
+
+ static JSC::Structure* createStructure(
+ JSC::JSGlobalObject* globalObject)
+ {
+ return internalCreateCommonJSModuleStructure(reinterpret_cast<Zig::GlobalObject*>(globalObject));
+ }
+
+ DECLARE_INFO;
+ template<typename, SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
+ {
+ if constexpr (mode == JSC::SubspaceAccess::Concurrently)
+ return nullptr;
+ return WebCore::subspaceForImpl<JSCommonJSModule, WebCore::UseCustomHeapCellType::No>(
+ vm,
+ [](auto& spaces) { return spaces.m_clientSubspaceForCommonJSModuleRecord.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForCommonJSModuleRecord = std::forward<decltype(space)>(space); },
+ [](auto& spaces) { return spaces.m_subspaceForCommonJSModuleRecord.get(); },
+ [](auto& spaces, auto&& space) { spaces.m_subspaceForCommonJSModuleRecord = std::forward<decltype(space)>(space); });
+ }
+
+ JSCommonJSModule(JSC::VM& vm, JSC::Structure* structure)
+ : Base(vm, structure)
+ {
+ }
+};
+
+Structure* createCommonJSModuleStructure(
+ Zig::GlobalObject* globalObject)
+{
+ return JSCommonJSModule::createStructure(globalObject);
+}
+
+static Structure* internalCreateCommonJSModuleStructure(
Zig::GlobalObject* globalObject)
{
auto& vm = globalObject->vm();
- JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(
+ JSC::Structure* structure = JSC::Structure::create(
+ vm,
globalObject,
globalObject->objectPrototype(),
+ JSC::TypeInfo(JSC::ObjectType, JSCommonJSModule::StructureFlags),
+ JSCommonJSModule::info(),
+ JSC::NonArray,
4);
JSC::PropertyOffset offset;
@@ -74,34 +232,34 @@ JSC::Structure* createCommonJSModuleStructure(
return structure;
}
-JSC::JSObject* createCommonJSModuleObject(
+template<typename Visitor>
+void JSCommonJSModule::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ JSCommonJSModule* thisObject = jsCast<JSCommonJSModule*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+ visitor.append(thisObject->m_exportsObject);
+ visitor.append(thisObject->m_id);
+}
+
+DEFINE_VISIT_CHILDREN(JSCommonJSModule);
+const JSC::ClassInfo JSCommonJSModule::s_info = { "Module"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCommonJSModule) };
+
+JSCommonJSModule* createCommonJSModuleObject(
Zig::GlobalObject* globalObject,
- const ResolvedSource& source, const WTF::String& sourceURL, JSC::JSValue exportsObjectValue, JSC::JSValue requireFunctionValue)
+ const ResolvedSource& source,
+ const WTF::String& sourceURL,
+ JSC::JSValue exportsObjectValue,
+ JSC::JSValue requireFunctionValue)
{
auto& vm = globalObject->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
-
- JSC::JSObject* moduleObject = JSC::constructEmptyObject(
- vm,
- globalObject->CommonJSModuleObjectStructure());
-
- RETURN_IF_EXCEPTION(scope, nullptr);
-
- moduleObject->putDirectOffset(
- vm,
- 0,
- exportsObjectValue);
-
auto* jsSourceURL = JSC::jsString(vm, sourceURL);
- moduleObject->putDirectOffset(
- vm,
- 1,
- jsSourceURL);
- moduleObject->putDirectOffset(
+ JSCommonJSModule* moduleObject = JSCommonJSModule::create(
vm,
- 2,
- // TODO: filename should be substring
+ globalObject->CommonJSModuleObjectStructure(),
+ exportsObjectValue,
jsSourceURL);
moduleObject->putDirectOffset(
@@ -146,21 +304,33 @@ JSC::SourceCode createCommonJSModule(
auto& vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto sourceCodeString = Zig::toString(source.source_code);
+ auto* requireMapKey = jsString(vm, sourceURL);
+
+ JSC::JSObject* exportsObject = source.commonJSExportsLen < 64
+ ? JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), source.commonJSExportsLen)
+ : JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
+
+ if (!globalObject->requireMap()->has(globalObject, requireMapKey)) {
+ globalObject->requireMap()->set(globalObject, requireMapKey, exportsObject);
+ }
+
JSC::SourceCode inputSource(
JSC::StringSourceProvider::create(sourceCodeString,
JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(sourceURL)),
sourceURL, TextPosition()));
+ JSC::Structure* scopeExtensionObjectStructure = globalObject->commonJSFunctionArgumentsStructure();
JSC::JSObject* scopeExtensionObject = JSC::constructEmptyObject(
vm,
- globalObject->commonJSFunctionArgumentsStructure());
+ scopeExtensionObjectStructure);
auto* requireFunction = Zig::ImportMetaObject::createRequireFunction(vm, globalObject, sourceURL);
- JSC::JSObject* exportsObject = source.commonJSExportsLen < 64
- ? JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), source.commonJSExportsLen)
- : JSC::constructEmptyObject(globalObject, globalObject->objectPrototype());
- auto* moduleObject = createCommonJSModuleObject(globalObject, source, sourceURL, exportsObject, requireFunction);
+ auto* moduleObject = createCommonJSModuleObject(globalObject,
+ source,
+ sourceURL,
+ exportsObject,
+ requireFunction);
scopeExtensionObject->putDirectOffset(
vm,
0,
@@ -180,47 +350,54 @@ JSC::SourceCode createCommonJSModule(
globalObject, inputSource, DerivedContextType::None, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None,
false, false, EvalContextType::None, nullptr, nullptr, ECMAMode::sloppy());
- RETURN_IF_EXCEPTION(throwScope, void());
-
- if (UNLIKELY(!executable)) {
+ if (UNLIKELY(!executable && !throwScope.exception())) {
throwSyntaxError(globalObject, throwScope, "Failed to compile CommonJS module."_s);
+ }
+
+ if (UNLIKELY(throwScope.exception())) {
+ globalObject->requireMap()->remove(globalObject, requireMapKey);
return;
}
- auto* contextScope = JSC::JSWithScope::create(vm, globalObject, globalObject->globalScope(), scopeExtensionObject);
- auto* requireMapKey = jsString(vm, sourceURL);
+ auto catchScope = DECLARE_CATCH_SCOPE(vm);
- globalObject->requireMap()->set(globalObject, requireMapKey, exportsObject);
+ JSC::JSWithScope* withScope = JSC::JSWithScope::create(vm, globalObject, globalObject->globalScope(), scopeExtensionObject);
+
+ vm.interpreter.executeEval(executable, globalObject, withScope);
- auto catchScope = DECLARE_CATCH_SCOPE(vm);
- vm.interpreter.executeEval(executable, globalObject, contextScope);
if (UNLIKELY(catchScope.exception())) {
auto returnedException = catchScope.exception();
catchScope.clearException();
- globalObject->requireMap()->remove(globalObject, requireMapKey);
JSC::throwException(globalObject, throwScope, returnedException);
}
- if (throwScope.exception())
+ if (throwScope.exception()) {
+ globalObject->requireMap()->remove(globalObject, requireMapKey);
return;
+ }
- JSValue result = moduleObject->getDirect(0);
+ JSValue result = moduleObject->exportsObject();
- if (result != exportsObject)
- globalObject->requireMap()->set(globalObject, requireMapKey, result);
+ globalObject->requireMap()->set(globalObject, requireMapKey, result);
exportNames.append(vm.propertyNames->defaultKeyword);
exportValues.append(result);
+
+ // This exists to tell ImportMetaObject.ts that this is a CommonJS module.
exportNames.append(Identifier::fromUid(vm.symbolRegistry().symbolForKey("CommonJS"_s)));
exportValues.append(jsNumber(0));
+ // This strong reference exists because otherwise it will crash when the finalizer runs.
+ exportNames.append(Identifier::fromUid(vm.symbolRegistry().symbolForKey("module"_s)));
+ exportValues.append(moduleObject);
+
if (result.isObject()) {
auto* exports = asObject(result);
auto* structure = exports->structure();
uint32_t size = structure->inlineSize() + structure->outOfLineSize();
- exportNames.reserveCapacity(size);
- exportValues.ensureCapacity(size);
+ exportNames.reserveCapacity(size + 3);
+ exportValues.ensureCapacity(size + 3);
if (canPerformFastEnumeration(structure)) {
exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool {
diff --git a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
index 75fff16a0..626b512be 100644
--- a/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMClientIsoSubspaces.h
@@ -33,6 +33,7 @@ public:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForRequireResolveFunction;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBundlerPlugin;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeVMScript;
+ std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForCommonJSModuleRecord;
#include "ZigGeneratedClasses+DOMClientIsoSubspaces.h"
/* --- bun --- */
diff --git a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
index 2b392a49d..c5767702a 100644
--- a/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
+++ b/src/bun.js/bindings/webcore/DOMIsoSubspaces.h
@@ -33,6 +33,8 @@ public:
std::unique_ptr<IsoSubspace> m_subspaceForRequireResolveFunction;
std::unique_ptr<IsoSubspace> m_subspaceForBundlerPlugin;
std::unique_ptr<IsoSubspace> m_subspaceForNodeVMScript;
+ std::unique_ptr<IsoSubspace> m_subspaceForCommonJSModuleRecord;
+
#include "ZigGeneratedClasses+DOMIsoSubspaces.h"
/*-- BUN --*/
diff --git a/src/bun.js/builtins/BunBuiltinNames.h b/src/bun.js/builtins/BunBuiltinNames.h
index 735141faa..640d122ca 100644
--- a/src/bun.js/builtins/BunBuiltinNames.h
+++ b/src/bun.js/builtins/BunBuiltinNames.h
@@ -84,6 +84,7 @@ using namespace JSC;
macro(errno) \
macro(errorSteps) \
macro(execArgv) \
+ macro(exports) \
macro(extname) \
macro(failureKind) \
macro(fatal) \
diff --git a/src/bun.js/builtins/WebCoreJSBuiltins.cpp b/src/bun.js/builtins/WebCoreJSBuiltins.cpp
index d572ad023..b6a0863a7 100644
--- a/src/bun.js/builtins/WebCoreJSBuiltins.cpp
+++ b/src/bun.js/builtins/WebCoreJSBuiltins.cpp
@@ -2196,9 +2196,9 @@ const char* const s_importMetaObjectLoadCJS2ESMCode = "(function (_){\"use stric
const JSC::ConstructAbility s_importMetaObjectRequireESMCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_importMetaObjectRequireESMCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_importMetaObjectRequireESMCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_importMetaObjectRequireESMCodeLength = 406;
+const int s_importMetaObjectRequireESMCodeLength = 419;
static const JSC::Intrinsic s_importMetaObjectRequireESMCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_importMetaObjectRequireESMCode = "(function (a){\"use strict\";var _=@Loader.registry.@get(a);if(!_||!_.evaluated)_=@loadCJS2ESM(a);if(!_||!_.evaluated||!_.module)@throwTypeError(`require() failed to evaluate module \"${a}\". This is an internal consistentency error.`);var i=@Loader.getModuleNamespaceObject(_.module),u=i.default,E=u\?.[@commonJSSymbol];if(E===0||i[@commonJSSymbol]===0)return u;else if(E&&@isCallable(u))return u();return i})\n";
+const char* const s_importMetaObjectRequireESMCode = "(function (a){\"use strict\";var i=@Loader.registry.@get(a);if(!i||!i.evaluated)i=@loadCJS2ESM(a);if(!i||!i.evaluated||!i.module)@throwTypeError(`require() failed to evaluate module \"${a}\". This is an internal consistentency error.`);var u=@Loader.getModuleNamespaceObject(i.module);if(u[@commonJSSymbol]===0)return;var E=u.default,_=E\?.[@commonJSSymbol];if(_===0)return E;else if(_&&@isCallable(E))return E();return u})\n";
// internalRequire
const JSC::ConstructAbility s_importMetaObjectInternalRequireCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
@@ -2212,9 +2212,9 @@ const char* const s_importMetaObjectInternalRequireCode = "(function (n){\"use s
const JSC::ConstructAbility s_importMetaObjectCreateRequireCacheCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_importMetaObjectCreateRequireCacheCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_importMetaObjectCreateRequireCacheCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_importMetaObjectCreateRequireCacheCodeLength = 888;
+const int s_importMetaObjectCreateRequireCacheCodeLength = 891;
static const JSC::Intrinsic s_importMetaObjectCreateRequireCacheCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_importMetaObjectCreateRequireCacheCode = "(function (){\"use strict\";class r{id;parent;filename;children=[];paths=[];constructor(_){this.id=_;const c=_.lastIndexOf(\"/\");if(c!==-1&&_.length>c+1)this.filename=_.substring(c+1);else this.filename=_}get loaded(){return!0}require(_){return @internalRequire(@resolveSync(_,this.id))}get exports(){return @requireMap.@get(this.id)\?\?{}}set exports(_){@requireMap.@set(this.id,_)}}var w=new Map;return new Proxy({},{get(_,c){if(@requireMap.@get(c)){var b=w.@get(c);if(!b)b=new r(c),w.@set(c,b);return b}},set(_,c,t){if(!w.@has(c))w.@set(c,new r(c));return @requireMap.@set(c,t\?.exports),!0},has(_,c){return @requireMap.@has(c)},deleteProperty(_,c){return w.@delete(c),@requireMap.@delete(c),@Loader.registry.@delete(c)},ownKeys(_){return[...@requireMap.@keys()]},getPrototypeOf(_){return null},getOwnPropertyDescriptor(_,c){if(@requireMap.@has(c))return{configurable:!0,enumerable:!0}}})})\n";
+const char* const s_importMetaObjectCreateRequireCacheCode = "(function (){\"use strict\";class r{id;parent;filename;children=[];paths=[];constructor(w){this.id=w;const c=w.lastIndexOf(\"/\");if(c!==-1&&w.length>c+1)this.filename=w.substring(c+1);else this.filename=w}get loaded(){return!0}require(w){return @internalRequire(@resolveSync(w,this.id))}get exports(){return @requireMap.@get(this.id)\?\?{}}set exports(w){@requireMap.@set(this.id,w)}}var _=new Map;return new Proxy({},{get(w,c){if(@requireMap.@get(c)){var g=_.@get(c);if(!g)g=new r(c),_.@set(c,g);return g}},set(w,c,b){if(!_.@has(c))_.@set(c,new r(c));return @requireMap.@set(c,b\?.exports),!0},has(w,c){return @requireMap.@has(c)},deleteProperty(w,c){return _.@delete(c),@requireMap.@delete(c),@Loader.registry.@delete(c),!0},ownKeys(w){return[...@requireMap.@keys()]},getPrototypeOf(w){return null},getOwnPropertyDescriptor(w,c){if(@requireMap.@has(c))return{configurable:!0,enumerable:!0}}})})\n";
// require
const JSC::ConstructAbility s_importMetaObjectRequireCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
diff --git a/src/bun.js/builtins/ts/ImportMetaObject.ts b/src/bun.js/builtins/ts/ImportMetaObject.ts
index 9255a591f..2df0f0c98 100644
--- a/src/bun.js/builtins/ts/ImportMetaObject.ts
+++ b/src/bun.js/builtins/ts/ImportMetaObject.ts
@@ -91,9 +91,15 @@ export function requireESM(this: ImportMetaObject, resolved) {
throw new TypeError(`require() failed to evaluate module "${resolved}". This is an internal consistentency error.`);
}
var exports = Loader.getModuleNamespaceObject(entry.module);
+ if (exports[$commonJSSymbol] === 0) {
+ // CommonJS module created via `Bun::CommonJSModuleRecord`
+ // We will refer to the requireMap to get the exports
+ return;
+ }
+
var commonJS = exports.default;
var cjs = commonJS?.[$commonJSSymbol];
- if (cjs === 0 || exports[$commonJSSymbol] === 0) {
+ if (cjs === 0) {
return commonJS;
} else if (cjs && $isCallable(commonJS)) {
return commonJS();
@@ -209,7 +215,8 @@ export function createRequireCache() {
deleteProperty(target, key: string) {
moduleMap.$delete(key);
$requireMap.$delete(key);
- return Loader.registry.$delete(key);
+ Loader.registry.$delete(key);
+ return true;
},
ownKeys(target) {
diff --git a/src/bundler/bundle_v2.zig b/src/bundler/bundle_v2.zig
index b0012c25c..967bfaa36 100644
--- a/src/bundler/bundle_v2.zig
+++ b/src/bundler/bundle_v2.zig
@@ -8572,6 +8572,7 @@ const LinkerContext = struct {
.const_values = c.graph.const_values,
.minify_whitespace = c.options.minify_whitespace,
.minify_syntax = c.options.minify_syntax,
+ .module_type = c.options.output_format,
.allocator = allocator,
.to_esm_ref = toESMRef,
diff --git a/test/cli/run/require-cache-fixture.cjs b/test/cli/run/require-cache-fixture.cjs
index 0186c4b75..012f60589 100644
--- a/test/cli/run/require-cache-fixture.cjs
+++ b/test/cli/run/require-cache-fixture.cjs
@@ -1,3 +1,6 @@
+// So it could be run in Node.js
+const Bun = (globalThis.Bun ??= { gc() {} });
+
const foo = require("./require-cache-fixture-b.cjs");
exports.foo = foo;
@@ -6,10 +9,16 @@ if (require.cache[require.resolve("./require-cache-fixture-b.cjs")].exports !==
throw new Error("exports.foo !== require.cache[require.resolve('./require-cache-fixture-b')]");
}
+Bun.gc(true);
+
delete require.cache[require.resolve("./require-cache-fixture-b.cjs")];
+Bun.gc(true);
+
exports.bar = require("./require-cache-fixture-b.cjs");
+Bun.gc(true);
+
if (require.cache[require.resolve("./require-cache-fixture-b.cjs")].exports !== exports.bar) {
throw new Error("exports.bar !== require.cache[require.resolve('./require-cache-fixture-b')]");
}
diff --git a/test/js/bun/websocket/websocket-server.test.ts b/test/js/bun/websocket/websocket-server.test.ts
index 7259fc8b6..7d43c7e65 100644
--- a/test/js/bun/websocket/websocket-server.test.ts
+++ b/test/js/bun/websocket/websocket-server.test.ts
@@ -1037,7 +1037,7 @@ describe("websocket server", () => {
});
expect(serverCounter).toBe(sendQueue.length);
server.stop(true);
- });
+ }, 10_000);
it("can close with reason and code #2631", done => {
let timeout: any;
let server = Bun.serve({