aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/bindings/CommonJSModuleRecord.cpp276
-rw-r--r--src/bun.js/bindings/CommonJSModuleRecord.h20
-rw-r--r--src/bun.js/bindings/ModuleLoader.cpp6
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp42
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h5
-rw-r--r--src/bun.js/bindings/exports.zig3
-rw-r--r--src/bun.js/bindings/headers-handwritten.h2
-rw-r--r--src/bun.js/builtins/WebCoreJSBuiltins.cpp8
-rw-r--r--src/bun.js/builtins/ts/ImportMetaObject.ts7
-rw-r--r--src/bun.js/module_loader.zig31
10 files changed, 395 insertions, 5 deletions
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.cpp b/src/bun.js/bindings/CommonJSModuleRecord.cpp
new file mode 100644
index 000000000..c77027983
--- /dev/null
+++ b/src/bun.js/bindings/CommonJSModuleRecord.cpp
@@ -0,0 +1,276 @@
+#include "root.h"
+#include "headers-handwritten.h"
+#include "ZigGlobalObject.h"
+#include "JavaScriptCore/JSSourceCode.h"
+#include "JavaScriptCore/JSString.h"
+#include "JavaScriptCore/JSValueInternal.h"
+#include "JavaScriptCore/JSVirtualMachineInternal.h"
+#include "JavaScriptCore/ObjectConstructor.h"
+#include "JavaScriptCore/OptionsList.h"
+#include "JavaScriptCore/ParserError.h"
+#include "JavaScriptCore/ScriptExecutable.h"
+#include "JavaScriptCore/SourceOrigin.h"
+#include "JavaScriptCore/StackFrame.h"
+#include "JavaScriptCore/StackVisitor.h"
+#include "BunClientData.h"
+#include "JavaScriptCore/Identifier.h"
+#include "ImportMetaObject.h"
+
+#include "JavaScriptCore/TypedArrayInlines.h"
+#include "JavaScriptCore/PropertyNameArray.h"
+#include "JavaScriptCore/JSWeakMap.h"
+#include "JavaScriptCore/JSWeakMapInlines.h"
+#include "JavaScriptCore/JSWithScope.h"
+
+#include <JavaScriptCore/DFGAbstractHeap.h>
+#include <JavaScriptCore/Completion.h>
+#include <JavaScriptCore/JSMap.h>
+
+#include <JavaScriptCore/JSMapInlines.h>
+
+namespace Bun {
+using namespace JSC;
+
+JSC::Structure* createCommonJSModuleStructure(
+ Zig::GlobalObject* globalObject)
+{
+ auto& vm = globalObject->vm();
+ JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(
+ globalObject,
+ globalObject->objectPrototype(),
+ 4);
+
+ JSC::PropertyOffset offset;
+ auto clientData = WebCore::clientData(vm);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "exports"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "id"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "fileName"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "require"_s),
+ JSC::PropertyAttribute::Builtin | JSC::PropertyAttribute::Function | 0,
+ offset);
+
+ return structure;
+}
+
+JSC::JSObject* createCommonJSModuleObject(
+ Zig::GlobalObject* globalObject,
+ 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(
+ vm,
+ 2,
+ // TODO: filename should be substring
+ jsSourceURL);
+
+ moduleObject->putDirectOffset(
+ vm,
+ 3,
+ requireFunctionValue);
+
+ return moduleObject;
+}
+
+static bool canPerformFastEnumeration(Structure* s)
+{
+ if (s->typeInfo().overridesGetOwnPropertySlot())
+ return false;
+ if (s->typeInfo().overridesAnyFormOfGetOwnPropertyNames())
+ return false;
+ if (hasIndexedProperties(s->indexingType()))
+ return false;
+ if (s->hasAnyKindOfGetterSetterProperties())
+ return false;
+ if (s->isUncacheableDictionary())
+ return false;
+ if (s->hasUnderscoreProtoPropertyExcludingOriginalProto())
+ return false;
+ return true;
+}
+
+JSC::SourceCode createCommonJSModule(
+ Zig::GlobalObject* globalObject,
+ ResolvedSource source)
+{
+
+ auto sourceURL = Zig::toStringCopy(source.source_url);
+
+ return JSC::SourceCode(
+ JSC::SyntheticSourceProvider::create(
+ [source, sourceURL](JSC::JSGlobalObject* lexicalGlobalObject,
+ JSC::Identifier moduleKey,
+ Vector<JSC::Identifier, 4>& exportNames,
+ JSC::MarkedArgumentBuffer& exportValues) -> void {
+ Zig::GlobalObject* globalObject = reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject);
+ auto& vm = globalObject->vm();
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto sourceCodeString = Zig::toString(source.source_code);
+ JSC::SourceCode inputSource(
+ JSC::StringSourceProvider::create(sourceCodeString,
+ JSC::SourceOrigin(WTF::URL::fileURLWithFileSystemPath(sourceURL)),
+ sourceURL, TextPosition()));
+
+ JSC::JSObject* scopeExtensionObject = JSC::constructEmptyObject(
+ vm,
+ globalObject->commonJSFunctionArgumentsStructure());
+
+ 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);
+ scopeExtensionObject->putDirectOffset(
+ vm,
+ 0,
+ moduleObject);
+
+ scopeExtensionObject->putDirectOffset(
+ vm,
+ 1,
+ exportsObject);
+
+ scopeExtensionObject->putDirectOffset(
+ vm,
+ 2,
+ requireFunction);
+
+ auto* executable = JSC::DirectEvalExecutable::create(
+ globalObject, inputSource, DerivedContextType::None, NeedsClassFieldInitializer::No, PrivateBrandRequirement::None,
+ false, false, EvalContextType::None, nullptr, nullptr, ECMAMode::sloppy());
+
+ RETURN_IF_EXCEPTION(throwScope, void());
+
+ if (UNLIKELY(!executable)) {
+ throwSyntaxError(globalObject, throwScope, "Failed to compile CommonJS module."_s);
+ return;
+ }
+
+ auto* contextScope = JSC::JSWithScope::create(vm, globalObject, globalObject->globalScope(), scopeExtensionObject);
+ auto* requireMapKey = jsString(vm, sourceURL);
+
+ globalObject->requireMap()->set(globalObject, requireMapKey, exportsObject);
+
+ 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())
+ return;
+
+ JSValue result = moduleObject->getDirect(0);
+
+ if (result != exportsObject)
+ globalObject->requireMap()->set(globalObject, requireMapKey, result);
+
+ exportNames.append(vm.propertyNames->defaultKeyword);
+ exportValues.append(result);
+ exportNames.append(Identifier::fromUid(vm.symbolRegistry().symbolForKey("CommonJS"_s)));
+ exportValues.append(jsNumber(0));
+
+ if (result.isObject()) {
+ auto* exports = asObject(result);
+
+ auto* structure = exports->structure();
+ uint32_t size = structure->inlineSize() + structure->outOfLineSize();
+ exportNames.reserveCapacity(size);
+ exportValues.ensureCapacity(size);
+
+ if (canPerformFastEnumeration(structure)) {
+ exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool {
+ auto key = entry.key();
+ if (key->isSymbol() || key == vm.propertyNames->defaultKeyword || entry.attributes() & PropertyAttribute::DontEnum)
+ return true;
+
+ exportNames.append(Identifier::fromUid(vm, key));
+ exportValues.append(exports->getDirect(entry.offset()));
+ return true;
+ });
+ } else {
+ JSC::PropertyNameArray properties(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
+ exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Exclude);
+ if (throwScope.exception())
+ return;
+
+ for (auto property : properties) {
+ if (UNLIKELY(property.isEmpty() || property.isNull()))
+ continue;
+
+ // ignore constructor
+ if (property == vm.propertyNames->constructor)
+ continue;
+
+ if (property.isSymbol() || property.isPrivateName() || property == vm.propertyNames->defaultKeyword)
+ continue;
+
+ JSC::PropertySlot slot(exports, PropertySlot::InternalMethodType::Get);
+ if (!exports->getPropertySlot(globalObject, property, slot))
+ continue;
+
+ exportNames.append(property);
+
+ JSValue getterResult = slot.getValue(globalObject, property);
+
+ // If it throws, we keep them in the exports list, but mark it as undefined
+ // This is consistent with what Node.js does.
+ if (catchScope.exception()) {
+ catchScope.clearException();
+ getterResult = jsUndefined();
+ }
+
+ exportValues.append(getterResult);
+ }
+ }
+ }
+ },
+ SourceOrigin(WTF::URL::fileURLWithFileSystemPath(sourceURL)),
+ sourceURL));
+}
+
+} \ No newline at end of file
diff --git a/src/bun.js/bindings/CommonJSModuleRecord.h b/src/bun.js/bindings/CommonJSModuleRecord.h
new file mode 100644
index 000000000..86daf875d
--- /dev/null
+++ b/src/bun.js/bindings/CommonJSModuleRecord.h
@@ -0,0 +1,20 @@
+#include "root.h"
+#include "headers-handwritten.h"
+
+namespace Zig {
+class GlobalObject;
+}
+namespace JSC {
+class SourceCode;
+}
+
+namespace Bun {
+
+JSC::Structure* createCommonJSModuleStructure(
+ Zig::GlobalObject* globalObject);
+
+JSC::SourceCode createCommonJSModule(
+ Zig::GlobalObject* globalObject,
+ ResolvedSource source);
+
+} // namespace Bun
diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp
index 75981f5b3..f4e96130b 100644
--- a/src/bun.js/bindings/ModuleLoader.cpp
+++ b/src/bun.js/bindings/ModuleLoader.cpp
@@ -35,6 +35,7 @@
#include "../modules/NodeModuleModule.h"
#include "../modules/TTYModule.h"
#include "node_util_types.h"
+#include "CommonJSModuleRecord.h"
namespace Bun {
using namespace Zig;
@@ -475,6 +476,11 @@ static JSValue fetchSourceCode(
Bun__transpileFile(bunVM, globalObject, specifier, referrer, res, false);
}
+ if (res->success && res->result.value.commonJSExportsLen) {
+ auto source = Bun::createCommonJSModule(globalObject, res->result.value);
+ return rejectOrResolve(JSSourceCode::create(vm, WTFMove(source)));
+ }
+
if (!res->success) {
throwException(scope, res->result.err, globalObject);
auto* exception = scope.exception();
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index f0ff9cf16..2a6be49b2 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -177,6 +177,7 @@ namespace JSCastingHelpers = JSC::JSCastingHelpers;
#include "CallSite.h"
#include "CallSitePrototype.h"
#include "DOMWrapperWorld-class.h"
+#include "CommonJSModuleRecord.h"
constexpr size_t DEFAULT_ERROR_STACK_TRACE_LIMIT = 10;
@@ -2607,6 +2608,45 @@ void GlobalObject::finishCreation(VM& vm)
init.set(result.toObject(globalObject));
});
+ m_commonJSModuleObjectStructure.initLater(
+ [](const Initializer<Structure>& init) {
+ init.set(Bun::createCommonJSModuleStructure(reinterpret_cast<Zig::GlobalObject*>(init.owner)));
+ });
+
+ m_commonJSFunctionArgumentsStructure.initLater(
+ [](const Initializer<Structure>& init) {
+ auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner);
+ JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(
+ globalObject,
+ globalObject->objectPrototype(),
+ 3);
+ JSC::PropertyOffset offset;
+ auto& vm = globalObject->vm();
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "module"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "exports"_s),
+ 0,
+ offset);
+
+ structure = structure->addPropertyTransition(
+ vm,
+ structure,
+ JSC::Identifier::fromString(vm, "require"_s),
+ JSC::PropertyAttribute::Function | JSC::PropertyAttribute::Builtin | 0,
+ offset);
+
+ init.set(structure);
+ });
+
// Change prototype from null to object for synthetic modules.
m_moduleNamespaceObjectStructure.initLater(
[](const Initializer<Structure>& init) {
@@ -3798,6 +3838,8 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_bunSleepThenCallback.visit(visitor);
thisObject->m_lazyTestModuleObject.visit(visitor);
thisObject->m_lazyPreloadTestModuleObject.visit(visitor);
+ thisObject->m_commonJSModuleObjectStructure.visit(visitor);
+ thisObject->m_commonJSFunctionArgumentsStructure.visit(visitor);
thisObject->m_cachedGlobalObjectStructure.visit(visitor);
thisObject->m_cachedGlobalProxyStructure.visit(visitor);
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index 67c3196c7..66853c909 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -260,6 +260,9 @@ public:
Structure* globalProxyStructure() { return m_cachedGlobalProxyStructure.getInitializedOnMainThread(this); }
JSObject* lazyTestModuleObject() { return m_lazyTestModuleObject.getInitializedOnMainThread(this); }
JSObject* lazyPreloadTestModuleObject() { return m_lazyPreloadTestModuleObject.getInitializedOnMainThread(this); }
+ Structure* CommonJSModuleObjectStructure() { return m_commonJSModuleObjectStructure.getInitializedOnMainThread(this); }
+
+ Structure* commonJSFunctionArgumentsStructure() { return m_commonJSFunctionArgumentsStructure.getInitializedOnMainThread(this); }
JSWeakMap* vmModuleContextMap() { return m_vmModuleContextMap.getInitializedOnMainThread(this); }
@@ -477,6 +480,8 @@ private:
LazyProperty<JSGlobalObject, JSFunction> m_bunSleepThenCallback;
LazyProperty<JSGlobalObject, Structure> m_cachedGlobalObjectStructure;
LazyProperty<JSGlobalObject, Structure> m_cachedGlobalProxyStructure;
+ LazyProperty<JSGlobalObject, Structure> m_commonJSModuleObjectStructure;
+ LazyProperty<JSGlobalObject, Structure> m_commonJSFunctionArgumentsStructure;
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
void* m_bunVM;
diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig
index 37fc7dabc..b993701fc 100644
--- a/src/bun.js/bindings/exports.zig
+++ b/src/bun.js/bindings/exports.zig
@@ -205,6 +205,9 @@ pub const ResolvedSource = extern struct {
specifier: ZigString,
source_code: ZigString,
source_url: ZigString,
+ commonjs_exports: ?[*]ZigString = null,
+ commonjs_exports_len: u32 = 0,
+
hash: u32,
allocator: ?*anyopaque,
diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h
index 673b366d1..d925fb4cd 100644
--- a/src/bun.js/bindings/headers-handwritten.h
+++ b/src/bun.js/bindings/headers-handwritten.h
@@ -25,6 +25,8 @@ typedef struct ResolvedSource {
ZigString specifier;
ZigString source_code;
ZigString source_url;
+ ZigString* commonJSExports;
+ uint32_t commonJSExportsLen;
uint32_t hash;
void* allocator;
uint64_t tag;
diff --git a/src/bun.js/builtins/WebCoreJSBuiltins.cpp b/src/bun.js/builtins/WebCoreJSBuiltins.cpp
index ab93a17ea..d572ad023 100644
--- a/src/bun.js/builtins/WebCoreJSBuiltins.cpp
+++ b/src/bun.js/builtins/WebCoreJSBuiltins.cpp
@@ -2196,17 +2196,17 @@ 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 = 382;
+const int s_importMetaObjectRequireESMCodeLength = 406;
static const JSC::Intrinsic s_importMetaObjectRequireESMCodeIntrinsic = JSC::NoIntrinsic;
-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 E=@Loader.getModuleNamespaceObject(i.module),_=E.default,b=_\?.[@commonJSSymbol];if(b===0)return _;else if(b&&@isCallable(_))return _();return E})\n";
+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";
// internalRequire
const JSC::ConstructAbility s_importMetaObjectInternalRequireCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_importMetaObjectInternalRequireCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_importMetaObjectInternalRequireCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_importMetaObjectInternalRequireCodeLength = 569;
+const int s_importMetaObjectInternalRequireCodeLength = 611;
static const JSC::Intrinsic s_importMetaObjectInternalRequireCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_importMetaObjectInternalRequireCode = "(function (n){\"use strict\";var _=@requireMap.@get(n);const i=n.substring(n.length-5);if(_){if(i===\".node\")return _.exports;return _}if(i===\".json\"){var S=globalThis[Symbol.for(\"_fs\")]||=@Bun.fs(),F=JSON.parse(S.readFileSync(n,\"utf8\"));return @requireMap.@set(n,F),F}else if(i===\".node\"){var b={exports:{}};return process.dlopen(b,n),@requireMap.@set(n,b),b.exports}else if(i===\".toml\"){var S=globalThis[Symbol.for(\"_fs\")]||=@Bun.fs(),F=@Bun.TOML.parse(S.readFileSync(n,\"utf8\"));return @requireMap.@set(n,F),F}else{var F=@requireESM(n);return @requireMap.@set(n,F),F}})\n";
+const char* const s_importMetaObjectInternalRequireCode = "(function (n){\"use strict\";var _=@requireMap.@get(n);const i=n.substring(n.length-5);if(_){if(i===\".node\")return _.exports;return _}if(i===\".json\"){var S=globalThis[Symbol.for(\"_fs\")]||=@Bun.fs(),F=JSON.parse(S.readFileSync(n,\"utf8\"));return @requireMap.@set(n,F),F}else if(i===\".node\"){var b={exports:{}};return process.dlopen(b,n),@requireMap.@set(n,b),b.exports}else if(i===\".toml\"){var S=globalThis[Symbol.for(\"_fs\")]||=@Bun.fs(),F=@Bun.TOML.parse(S.readFileSync(n,\"utf8\"));return @requireMap.@set(n,F),F}else{var F=@requireESM(n);const j=@requireMap.@get(n);if(j)return j;return @requireMap.@set(n,F),F}})\n";
// createRequireCache
const JSC::ConstructAbility s_importMetaObjectCreateRequireCacheCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
diff --git a/src/bun.js/builtins/ts/ImportMetaObject.ts b/src/bun.js/builtins/ts/ImportMetaObject.ts
index 9ce53c192..9255a591f 100644
--- a/src/bun.js/builtins/ts/ImportMetaObject.ts
+++ b/src/bun.js/builtins/ts/ImportMetaObject.ts
@@ -93,7 +93,7 @@ export function requireESM(this: ImportMetaObject, resolved) {
var exports = Loader.getModuleNamespaceObject(entry.module);
var commonJS = exports.default;
var cjs = commonJS?.[$commonJSSymbol];
- if (cjs === 0) {
+ if (cjs === 0 || exports[$commonJSSymbol] === 0) {
return commonJS;
} else if (cjs && $isCallable(commonJS)) {
return commonJS();
@@ -130,6 +130,11 @@ export function internalRequire(this: ImportMetaObject, resolved) {
return exports;
} else {
var exports = $requireESM(resolved);
+ const cachedExports = $requireMap.$get(resolved);
+ if (cachedExports) {
+ return cachedExports;
+ }
+
$requireMap.$set(resolved, exports);
return exports;
}
diff --git a/src/bun.js/module_loader.zig b/src/bun.js/module_loader.zig
index 6524c8084..635e0f4a9 100644
--- a/src/bun.js/module_loader.zig
+++ b/src/bun.js/module_loader.zig
@@ -820,11 +820,26 @@ pub const ModuleLoader = struct {
return resolved_source;
}
+ var commonjs_exports = try bun.default_allocator.alloc(ZigString, parse_result.ast.commonjs_export_names.len);
+ for (parse_result.ast.commonjs_export_names, commonjs_exports) |name, *out| {
+ out.* = ZigString.fromUTF8(name);
+ }
+
return ResolvedSource{
.allocator = null,
.source_code = ZigString.init(try default_allocator.dupe(u8, printer.ctx.getWritten())),
.specifier = ZigString.init(specifier),
.source_url = ZigString.init(path.text),
+ .commonjs_exports = if (commonjs_exports.len > 0)
+ commonjs_exports.ptr
+ else
+ null,
+ .commonjs_exports_len = if (commonjs_exports.len > 0)
+ @truncate(u32, commonjs_exports.len)
+ else if (parse_result.ast.exports_kind == .cjs)
+ std.math.maxInt(u32)
+ else
+ 0,
// // TODO: change hash to a bitfield
// .hash = 1,
@@ -943,6 +958,7 @@ pub const ModuleLoader = struct {
.virtual_source = virtual_source,
.hoist_bun_plugin = true,
.dont_bundle_twice = true,
+ .allow_commonjs = true,
.inject_jest_globals = jsc_vm.bundler.options.rewrite_jest_for_tests and
jsc_vm.main.len == path.text.len and
jsc_vm.main_hash == hash and
@@ -1146,11 +1162,26 @@ pub const ModuleLoader = struct {
return resolved_source;
}
+ var commonjs_exports = try bun.default_allocator.alloc(ZigString, parse_result.ast.commonjs_export_names.len);
+ for (parse_result.ast.commonjs_export_names, commonjs_exports) |name, *out| {
+ out.* = ZigString.fromUTF8(name);
+ }
+
return .{
.allocator = null,
.source_code = ZigString.init(try default_allocator.dupe(u8, printer.ctx.getWritten())),
.specifier = ZigString.init(display_specifier),
.source_url = ZigString.init(path.text),
+ .commonjs_exports = if (commonjs_exports.len > 0)
+ commonjs_exports.ptr
+ else
+ null,
+ .commonjs_exports_len = if (commonjs_exports.len > 0)
+ @truncate(u32, commonjs_exports.len)
+ else if (parse_result.ast.exports_kind == .cjs)
+ std.math.maxInt(u32)
+ else
+ 0,
// // TODO: change hash to a bitfield
// .hash = 1,