diff options
Diffstat (limited to 'src/bun.js')
-rw-r--r-- | src/bun.js/bindings/CommonJSModuleRecord.cpp | 276 | ||||
-rw-r--r-- | src/bun.js/bindings/CommonJSModuleRecord.h | 20 | ||||
-rw-r--r-- | src/bun.js/bindings/ModuleLoader.cpp | 6 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 42 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 5 | ||||
-rw-r--r-- | src/bun.js/bindings/exports.zig | 3 | ||||
-rw-r--r-- | src/bun.js/bindings/headers-handwritten.h | 2 | ||||
-rw-r--r-- | src/bun.js/builtins/WebCoreJSBuiltins.cpp | 8 | ||||
-rw-r--r-- | src/bun.js/builtins/ts/ImportMetaObject.ts | 7 | ||||
-rw-r--r-- | src/bun.js/module_loader.zig | 31 |
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, |