aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp13
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h2
-rw-r--r--src/bun.js/builtins/BunBuiltinNames.h2
-rw-r--r--src/bun.js/builtins/cpp/JSZigGlobalObjectBuiltins.cpp183
-rw-r--r--src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h1
-rw-r--r--src/bun.js/builtins/js/JSZigGlobalObject.js24
-rw-r--r--src/bundler/entry_points.zig6
-rw-r--r--src/bundler/generate_node_modules_bundle.zig2
-rw-r--r--src/import_record.zig4
-rw-r--r--src/js_ast.zig16
-rw-r--r--src/js_printer.zig152
-rw-r--r--src/linker.zig34
12 files changed, 272 insertions, 167 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp
index a51bc433b..6f04d2d1f 100644
--- a/src/bun.js/bindings/ZigGlobalObject.cpp
+++ b/src/bun.js/bindings/ZigGlobalObject.cpp
@@ -1754,6 +1754,12 @@ void GlobalObject::finishCreation(VM& vm)
init.set(map);
});
+ m_requireMap.initLater(
+ [](const JSC::LazyProperty<JSC::JSGlobalObject, JSC::JSMap>::Initializer& init) {
+ auto* map = JSC::JSMap::create(init.owner, init.vm, init.owner->mapStructure());
+ init.set(map);
+ });
+
m_JSArrayBufferSinkClassStructure.initLater(
[](LazyClassStructure::Initializer& init) {
auto* prototype = createJSSinkPrototype(init.vm, init.global, WebCore::SinkID::ArrayBufferSink);
@@ -1784,7 +1790,7 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
auto& builtinNames = WebCore::builtinNames(vm);
WTF::Vector<GlobalPropertyInfo> extraStaticGlobals;
- extraStaticGlobals.reserveCapacity(30);
+ extraStaticGlobals.reserveCapacity(31);
JSC::Identifier queueMicrotaskIdentifier = JSC::Identifier::fromString(vm, "queueMicrotask"_s);
extraStaticGlobals.uncheckedAppend(
@@ -1848,6 +1854,7 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DontDelete | 0 });
static NeverDestroyed<const String> BunLazyString(MAKE_STATIC_STRING_IMPL("Bun.lazy"));
+ static NeverDestroyed<const String> CommonJSSymbolKey(MAKE_STATIC_STRING_IMPL("CommonJS"));
JSC::Identifier BunLazyIdentifier = JSC::Identifier::fromUid(vm.symbolRegistry().symbolForKey(BunLazyString));
JSC::JSFunction* lazyLoadFunction = JSC::JSFunction::create(vm, JSC::jsCast<JSC::JSGlobalObject*>(globalObject()), 0,
BunLazyString, functionLazyLoad);
@@ -1878,6 +1885,9 @@ void GlobalObject::addBuiltinGlobals(JSC::VM& vm)
extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.getInternalWritableStreamPrivateName(), JSFunction::create(vm, this, 1, String(), getInternalWritableStream), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.createWritableStreamFromInternalPrivateName(), JSFunction::create(vm, this, 1, String(), createWritableStreamFromInternal), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.fulfillModuleSyncPrivateName(), JSFunction::create(vm, this, 1, String(), functionFulfillModuleSync), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::Function));
+
+ extraStaticGlobals.uncheckedAppend(GlobalPropertyInfo(builtinNames.commonJSSymbolPrivateName(), JSC::Symbol::create(vm, vm.symbolRegistry().symbolForKey(CommonJSSymbolKey)), PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly));
+
this->addStaticGlobals(extraStaticGlobals.data(), extraStaticGlobals.size());
extraStaticGlobals.releaseBuffer();
@@ -2134,6 +2144,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor)
thisObject->m_JSArrayBufferControllerPrototype.visit(visitor);
thisObject->m_importMetaObjectStructure.visit(visitor);
thisObject->m_lazyReadableStreamPrototypeMap.visit(visitor);
+ thisObject->m_requireMap.visit(visitor);
visitor.append(thisObject->m_readableStreamToArrayBufferResolve);
visitor.append(thisObject->m_readableStreamToText);
diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h
index cabaf57a9..b5a2f99da 100644
--- a/src/bun.js/bindings/ZigGlobalObject.h
+++ b/src/bun.js/bindings/ZigGlobalObject.h
@@ -159,6 +159,7 @@ public:
JSC::JSValue ArrayBufferSinkPrototype() { return m_JSArrayBufferSinkClassStructure.prototypeInitializedOnMainThread(this); }
JSC::JSValue JSReadableArrayBufferSinkControllerPrototype() { return m_JSArrayBufferControllerPrototype.getInitializedOnMainThread(this); }
JSC::JSMap* readableStreamNativeMap() { return m_lazyReadableStreamPrototypeMap.getInitializedOnMainThread(this); }
+ JSC::JSMap* requireMap() { return m_requireMap.getInitializedOnMainThread(this); }
void* bunVM() { return m_bunVM; }
bool isThreadLocalDefaultGlobalObject = false;
@@ -186,6 +187,7 @@ private:
LazyProperty<JSGlobalObject, JSObject> m_JSArrayBufferControllerPrototype;
LazyProperty<JSGlobalObject, JSObject> m_importMetaObjectStructure;
LazyProperty<JSGlobalObject, JSMap> m_lazyReadableStreamPrototypeMap;
+ LazyProperty<JSGlobalObject, JSMap> m_requireMap;
DOMGuardedObjectSet m_guardedObjects WTF_GUARDED_BY_LOCK(m_gcLock);
void* m_bunVM;
diff --git a/src/bun.js/builtins/BunBuiltinNames.h b/src/bun.js/builtins/BunBuiltinNames.h
index 6acd30a8b..c41d368b4 100644
--- a/src/bun.js/builtins/BunBuiltinNames.h
+++ b/src/bun.js/builtins/BunBuiltinNames.h
@@ -62,6 +62,7 @@ using namespace JSC;
macro(closedPromise) \
macro(closedPromiseCapability) \
macro(code) \
+ macro(commonJSSymbol) \
macro(connect) \
macro(consumeReadableStream) \
macro(controlledReadableStream) \
@@ -177,6 +178,7 @@ using namespace JSC;
macro(releaseLock) \
macro(removeEventListener) \
macro(require) \
+ macro(requireMap) \
macro(requireModule) \
macro(resolve) \
macro(resolveSync) \
diff --git a/src/bun.js/builtins/cpp/JSZigGlobalObjectBuiltins.cpp b/src/bun.js/builtins/cpp/JSZigGlobalObjectBuiltins.cpp
index 421ba1181..583a035d8 100644
--- a/src/bun.js/builtins/cpp/JSZigGlobalObjectBuiltins.cpp
+++ b/src/bun.js/builtins/cpp/JSZigGlobalObjectBuiltins.cpp
@@ -49,7 +49,7 @@ namespace WebCore {
const JSC::ConstructAbility s_jsZigGlobalObjectRequireCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_jsZigGlobalObjectRequireCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_jsZigGlobalObjectRequireCodeLength = 1221;
+const int s_jsZigGlobalObjectRequireCodeLength = 1162;
static const JSC::Intrinsic s_jsZigGlobalObjectRequireCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_jsZigGlobalObjectRequireCode =
"(function (name) {\n" \
@@ -59,36 +59,36 @@ const char* const s_jsZigGlobalObjectRequireCode =
" }\n" \
" \n" \
" const resolved = this.resolveSync(name, this.path);\n" \
- " var requireCache = (globalThis[Symbol.for(\"_requireCache\")] ||= new @Map);\n" \
- " var cached = requireCache.@get(resolved);\n" \
+ " var cached = @requireMap.@get(resolved);\n" \
+ " const last5 = resolved.substring(resolved.length - 5);\n" \
" if (cached) {\n" \
- " if (resolved.endsWith(\".node\")) {\n" \
+ " if (last5 === \".node\") {\n" \
" return cached.exports;\n" \
" }\n" \
"\n" \
" return cached;\n" \
" }\n" \
"\n" \
- "\n" \
+ " \n" \
" //\n" \
- " if (resolved.endsWith(\".json\")) {\n" \
+ " if (last5 === \".json\") {\n" \
" var fs = (globalThis[Symbol.for(\"_fs\")] ||= Bun.fs());\n" \
" var exports = JSON.parse(fs.readFileSync(resolved, \"utf8\"));\n" \
- " requireCache.@set(resolved, exports);\n" \
+ " @requireMap.@set(resolved, exports);\n" \
" return exports;\n" \
- " } else if (resolved.endsWith(\".node\")) {\n" \
+ " } else if (last5 === \".node\") {\n" \
" var module = { exports: {} };\n" \
" globalThis.process.dlopen(module, resolved);\n" \
- " requireCache.@set(resolved, module);\n" \
+ " @requireMap.@set(resolved, module);\n" \
" return module.exports;\n" \
- " } else if (resolved.endsWith(\".toml\")) {\n" \
+ " } else if (last5 === \".toml\") {\n" \
" var fs = (globalThis[Symbol.for(\"_fs\")] ||= Bun.fs());\n" \
" var exports = Bun.TOML.parse(fs.readFileSync(resolved, \"utf8\"));\n" \
- " requireCache.@set(resolved, exports);\n" \
+ " @requireMap.@set(resolved, exports);\n" \
" return exports;\n" \
" } else {\n" \
" var exports = this.requireModule(this, resolved);\n" \
- " requireCache.@set(resolved, exports);\n" \
+ " @requireMap.@set(resolved, exports);\n" \
" return exports;\n" \
" }\n" \
"})\n" \
@@ -96,94 +96,117 @@ const char* const s_jsZigGlobalObjectRequireCode =
const JSC::ConstructAbility s_jsZigGlobalObjectLoadModuleCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_jsZigGlobalObjectLoadModuleCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_jsZigGlobalObjectLoadModuleCodeLength = 2783;
+const int s_jsZigGlobalObjectLoadModuleCodeLength = 2750;
static const JSC::Intrinsic s_jsZigGlobalObjectLoadModuleCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_jsZigGlobalObjectLoadModuleCode =
"(function (meta, resolvedSpecifier) {\n" \
" \"use strict\";\n" \
- " var queue = @createFIFO();\n" \
- " var key = resolvedSpecifier;\n" \
- " \n" \
- " var Loader = globalThis.Loader;\n" \
- " var registry = Loader.registry;\n" \
- " while (key) {\n" \
- " @fulfillModuleSync(key);\n" \
- " var entry = registry.@get(key);\n" \
+ " var Loader = globalThis.Loader;\n" \
"\n" \
- " //\n" \
- " //\n" \
- " //\n" \
- " //\n" \
- " var sourceCodeObject = @getPromiseInternalField(entry.fetch, @promiseFieldReactionsOrResult);\n" \
- " \n" \
+ " var queue = @createFIFO();\n" \
+ " var key = resolvedSpecifier;\n" \
+ " var registry = Loader.registry;\n" \
+ " while (key) {\n" \
+ " @fulfillModuleSync(key);\n" \
+ " var entry = registry.@get(key);\n" \
+ "\n" \
+ " //\n" \
+ " //\n" \
+ " //\n" \
+ " //\n" \
+ " var sourceCodeObject = @getPromiseInternalField(\n" \
+ " entry.fetch,\n" \
+ " @promiseFieldReactionsOrResult\n" \
+ " );\n" \
+ "\n" \
+ " //\n" \
+ " //\n" \
+ " //\n" \
+ " var moduleRecordPromise = Loader.parseModule(key, sourceCodeObject);\n" \
+ " var module = entry.module;\n" \
+ " if (!module && moduleRecordPromise && @isPromise(moduleRecordPromise)) {\n" \
+ " var reactionsOrResult = @getPromiseInternalField(\n" \
+ " moduleRecordPromise,\n" \
+ " @promiseFieldReactionsOrResult\n" \
+ " );\n" \
+ " var flags = @getPromiseInternalField(\n" \
+ " moduleRecordPromise,\n" \
+ " @promiseFieldFlags\n" \
+ " );\n" \
+ " var state = flags & @promiseStateMask;\n" \
"\n" \
" //\n" \
+ " if (\n" \
+ " state === @promiseStatePending ||\n" \
+ " (reactionsOrResult && @isPromise(reactionsOrResult))\n" \
+ " ) {\n" \
+ " @throwTypeError(`require() async module \\\"${key}\\\" is unsupported`);\n" \
+ " } else if (state === @promiseStateRejected) {\n" \
+ " //\n" \
+ " //\n" \
+ " @throwTypeError(\n" \
+ " `${\n" \
+ " reactionsOrResult?.message ?? \"An error occurred\"\n" \
+ " } while parsing module \\\"${key}\\\"`\n" \
+ " );\n" \
+ " }\n" \
+ " entry.module = module = reactionsOrResult;\n" \
+ " } else if (moduleRecordPromise && !module) {\n" \
+ " entry.module = module = moduleRecordPromise;\n" \
+ " }\n" \
+ "\n" \
+ " //\n" \
+ " @setStateToMax(entry, @ModuleLink);\n" \
+ " var dependenciesMap = module.dependenciesMap;\n" \
+ " var requestedModules = Loader.requestedModules(module);\n" \
+ " var dependencies = @newArrayWithSize(requestedModules.length);\n" \
+ "\n" \
+ " for (var i = 0, length = requestedModules.length; i < length; ++i) {\n" \
+ " var depName = requestedModules[i];\n" \
+ "\n" \
" //\n" \
" //\n" \
- " var moduleRecordPromise = Loader.parseModule(key, sourceCodeObject);\n" \
- " var module = entry.module;\n" \
- " if (!module && moduleRecordPromise && @isPromise(moduleRecordPromise)) {\n" \
- " var reactionsOrResult = @getPromiseInternalField(moduleRecordPromise, @promiseFieldReactionsOrResult);\n" \
- " var flags = @getPromiseInternalField(moduleRecordPromise, @promiseFieldFlags);\n" \
- " var state = flags & @promiseStateMask;\n" \
+ " var depKey =\n" \
+ " depName[0] === \"/\"\n" \
+ " ? depName\n" \
+ " : Loader.resolveSync(depName, key, @undefined);\n" \
+ " var depEntry = Loader.ensureRegistered(depKey);\n" \
"\n" \
- " //\n" \
- " if (state === @promiseStatePending || (reactionsOrResult && @isPromise(reactionsOrResult))) {\n" \
- " @throwTypeError(`require() async module \\\"${key}\\\" is unsupported`);\n" \
- " \n" \
- " } else if (state === @promiseStateRejected) {\n" \
- " //\n" \
- " //\n" \
- " @throwTypeError(`${reactionsOrResult?.message ?? \"An error occurred\"} while parsing module \\\"${key}\\\"`);\n" \
- " }\n" \
- " entry.module = module = reactionsOrResult;\n" \
- " } else if (moduleRecordPromise && !module) {\n" \
- " entry.module = module = moduleRecordPromise;\n" \
+ " if (depEntry.state < @ModuleLink) {\n" \
+ " queue.push(depKey);\n" \
" }\n" \
"\n" \
- " //\n" \
- " @setStateToMax(entry, @ModuleLink);\n" \
- " var dependenciesMap = module.dependenciesMap;\n" \
- " var requestedModules = Loader.requestedModules(module);\n" \
- " var dependencies = @newArrayWithSize(requestedModules.length);\n" \
- " \n" \
- " for (var i = 0, length = requestedModules.length; i < length; ++i) {\n" \
- " var depName = requestedModules[i];\n" \
- "\n" \
- " //\n" \
- " //\n" \
- " var depKey = depName[0] === '/' ? depName : Loader.resolveSync(depName, key, @undefined);\n" \
- " var depEntry = Loader.ensureRegistered(depKey);\n" \
- "\n" \
- " if (depEntry.state < @ModuleLink) {\n" \
- " queue.push(depKey);\n" \
- " }\n" \
- "\n" \
- " @putByValDirect(dependencies, i, depEntry);\n" \
- " dependenciesMap.@set(depName, depEntry);\n" \
- " }\n" \
- "\n" \
- " entry.dependencies = dependencies;\n" \
- " key = queue.shift();\n" \
- " while (key && ((registry.@get(key)?.state ?? @ModuleFetch) >= @ModuleLink)) {\n" \
- " key = queue.shift();\n" \
- " }\n" \
+ " @putByValDirect(dependencies, i, depEntry);\n" \
+ " dependenciesMap.@set(depName, depEntry);\n" \
" }\n" \
"\n" \
- " var linkAndEvaluateResult = Loader.linkAndEvaluateModule(resolvedSpecifier, @undefined);\n" \
- " if (linkAndEvaluateResult && @isPromise(linkAndEvaluateResult)) {\n" \
- " //\n" \
- " //\n" \
- " @throwTypeError(`require() async module \\\"${resolvedSpecifier}\\\" is unsupported`);\n" \
+ " entry.dependencies = dependencies;\n" \
+ " key = queue.shift();\n" \
+ " while (key && (registry.@get(key)?.state ?? @ModuleFetch) >= @ModuleLink) {\n" \
+ " key = queue.shift();\n" \
" }\n" \
+ " }\n" \
+ "\n" \
+ " var linkAndEvaluateResult = Loader.linkAndEvaluateModule(\n" \
+ " resolvedSpecifier,\n" \
+ " @undefined\n" \
+ " );\n" \
+ " if (linkAndEvaluateResult && @isPromise(linkAndEvaluateResult)) {\n" \
+ " //\n" \
+ " //\n" \
+ " @throwTypeError(\n" \
+ " `require() async module \\\"${resolvedSpecifier}\\\" is unsupported`\n" \
+ " );\n" \
+ " }\n" \
+ "\n" \
+ " return Loader.registry.@get(resolvedSpecifier);\n" \
"\n" \
- " return Loader.registry.@get(resolvedSpecifier);\n" \
"})\n" \
;
const JSC::ConstructAbility s_jsZigGlobalObjectRequireModuleCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_jsZigGlobalObjectRequireModuleCodeConstructorKind = JSC::ConstructorKind::None;
-const int s_jsZigGlobalObjectRequireModuleCodeLength = 613;
+const int s_jsZigGlobalObjectRequireModuleCodeLength = 606;
static const JSC::Intrinsic s_jsZigGlobalObjectRequireModuleCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_jsZigGlobalObjectRequireModuleCode =
"(function (meta, resolved) {\n" \
@@ -200,7 +223,7 @@ const char* const s_jsZigGlobalObjectRequireModuleCode =
" }\n" \
" var exports = Loader.getModuleNamespaceObject(entry.module);\n" \
" var commonJS = exports.default;\n" \
- " if (commonJS && @isObject(commonJS) && Symbol.for(\"CommonJS\") in commonJS) {\n" \
+ " if (commonJS && @isObject(commonJS) && @commonJSSymbol in commonJS) {\n" \
" return commonJS();\n" \
" }\n" \
" return exports;\n" \
diff --git a/src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h b/src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h
index fc5e2406a..cefa5fd8c 100644
--- a/src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h
+++ b/src/bun.js/builtins/cpp/WebCoreJSBuiltinInternals.h
@@ -82,6 +82,7 @@ namespace Zig { class GlobalObject; }
namespace Zig { class GlobalObject; }
namespace Zig { class GlobalObject; }
namespace Zig { class GlobalObject; }
+namespace Zig { class GlobalObject; }
/*
* Copyright (c) 2015 Igalia
* Copyright (c) 2015 Igalia S.L.
diff --git a/src/bun.js/builtins/js/JSZigGlobalObject.js b/src/bun.js/builtins/js/JSZigGlobalObject.js
index 7b82067ec..bb08bb107 100644
--- a/src/bun.js/builtins/js/JSZigGlobalObject.js
+++ b/src/bun.js/builtins/js/JSZigGlobalObject.js
@@ -30,36 +30,36 @@ function require(name) {
}
const resolved = this.resolveSync(name, this.path);
- var requireCache = (globalThis[Symbol.for("_requireCache")] ||= new @Map);
- var cached = requireCache.@get(resolved);
+ var cached = @requireMap.@get(resolved);
+ const last5 = resolved.substring(resolved.length - 5);
if (cached) {
- if (resolved.endsWith(".node")) {
+ if (last5 === ".node") {
return cached.exports;
}
return cached;
}
-
+
// TODO: remove this hardcoding
- if (resolved.endsWith(".json")) {
+ if (last5 === ".json") {
var fs = (globalThis[Symbol.for("_fs")] ||= Bun.fs());
var exports = JSON.parse(fs.readFileSync(resolved, "utf8"));
- requireCache.@set(resolved, exports);
+ @requireMap.@set(resolved, exports);
return exports;
- } else if (resolved.endsWith(".node")) {
+ } else if (last5 === ".node") {
var module = { exports: {} };
globalThis.process.dlopen(module, resolved);
- requireCache.@set(resolved, module);
+ @requireMap.@set(resolved, module);
return module.exports;
- } else if (resolved.endsWith(".toml")) {
+ } else if (last5 === ".toml") {
var fs = (globalThis[Symbol.for("_fs")] ||= Bun.fs());
var exports = Bun.TOML.parse(fs.readFileSync(resolved, "utf8"));
- requireCache.@set(resolved, exports);
+ @requireMap.@set(resolved, exports);
return exports;
} else {
var exports = this.requireModule(this, resolved);
- requireCache.@set(resolved, exports);
+ @requireMap.@set(resolved, exports);
return exports;
}
}
@@ -182,7 +182,7 @@ function requireModule(meta, resolved) {
}
var exports = Loader.getModuleNamespaceObject(entry.module);
var commonJS = exports.default;
- if (commonJS && @isObject(commonJS) && Symbol.for("CommonJS") in commonJS) {
+ if (commonJS && @isObject(commonJS) && @commonJSSymbol in commonJS) {
return commonJS();
}
return exports;
diff --git a/src/bundler/entry_points.zig b/src/bundler/entry_points.zig
index d2ffc4794..fec040bd2 100644
--- a/src/bundler/entry_points.zig
+++ b/src/bundler/entry_points.zig
@@ -183,11 +183,13 @@ pub const ServerEntryPoint = struct {
const code = try std.fmt.bufPrint(
&entry.code_buffer,
\\//Auto-generated file
+ \\var cjsSymbol = Symbol.for("CommonJS");
\\import * as start from '{s}{s}';
\\export * from '{s}{s}';
\\var entryNamespace = start;
- \\if ('default' in start && "__internalIsCommonJSNamespace" in globalThis && __internalIsCommonJSNamespace(start)) {{
- \\ entryNamespace = start.default();
+ \\var cjs = start?.default;
+ \\if (cjs && typeof cjs === 'function' && cjsSymbol in cjs) {{
+ \\ entryNamespace = cjs();
\\}}
\\if (typeof entryNamespace?.then === 'function') {{
\\ entryNamespace = entryNamespace.then((entryNamespace) => {{
diff --git a/src/bundler/generate_node_modules_bundle.zig b/src/bundler/generate_node_modules_bundle.zig
index a269944af..f48dcf217 100644
--- a/src/bundler/generate_node_modules_bundle.zig
+++ b/src/bundler/generate_node_modules_bundle.zig
@@ -1323,7 +1323,7 @@ pub fn processFile(this: *GenerateNodeModuleBundle, worker: *ThreadPool.Worker,
if (bundler.options.platform.isBun()) {
if (JSC.DisabledModule.has(import_record.path.text)) {
import_record.path.is_disabled = true;
- import_record.wrap_with_to_module = true;
+ import_record.do_commonjs_transform_in_printer = true;
import_record.is_bundled = true;
continue;
}
diff --git a/src/import_record.zig b/src/import_record.zig
index a16e5a8ad..a933df2fb 100644
--- a/src/import_record.zig
+++ b/src/import_record.zig
@@ -125,8 +125,8 @@ pub const ImportRecord = struct {
/// calling the "__reExport()" helper function
calls_run_time_re_export_fn: bool = false,
- /// Tell the printer to wrap this call to "require()" in "__toModule(...)"
- wrap_with_to_module: bool = false,
+ /// Tell the printer to use runtime code to resolve this import/export
+ do_commonjs_transform_in_printer: bool = false,
/// True for require calls like this: "try { require() } catch {}". In this
/// case we shouldn't generate an error if the path could not be resolved.
diff --git a/src/js_ast.zig b/src/js_ast.zig
index 54b3bbbeb..bacf0cd6d 100644
--- a/src/js_ast.zig
+++ b/src/js_ast.zig
@@ -494,14 +494,14 @@ pub const ClauseItem = struct {
alias_loc: logger.Loc,
name: LocRef,
- // This is the original name of the symbol stored in "Name". It's needed for
- // "SExportClause" statements such as this:
- //
- // export {foo as bar} from 'path'
- //
- // In this case both "foo" and "bar" are aliases because it's a re-export.
- // We need to preserve both aliases in case the symbol is renamed. In this
- // example, "foo" is "OriginalName" and "bar" is "Alias".
+ /// This is the original name of the symbol stored in "Name". It's needed for
+ /// "SExportClause" statements such as this:
+ ///
+ /// export {foo as bar} from 'path'
+ ///
+ /// In this case both "foo" and "bar" are aliases because it's a re-export.
+ /// We need to preserve both aliases in case the symbol is renamed. In this
+ /// example, "foo" is "OriginalName" and "bar" is "Alias".
original_name: string,
pub const default_alias: string = "default";
diff --git a/src/js_printer.zig b/src/js_printer.zig
index 8f5f47e20..5f0e99ded 100644
--- a/src/js_printer.zig
+++ b/src/js_printer.zig
@@ -379,7 +379,6 @@ pub const Options = struct {
rewrite_require_resolve: bool = true,
allocator: std.mem.Allocator = default_allocator,
source_map_handler: ?SourceMapHandler = null,
-
css_import_behavior: Api.CssInJsBehavior = Api.CssInJsBehavior.facade,
// TODO: remove this
@@ -542,6 +541,8 @@ pub fn NewPrinter(
prev_stmt_tag: Stmt.Tag = .s_empty,
source_map_builder: SourceMap.Chunk.Builder = undefined,
+ symbol_counter: u32 = 0,
+
const Printer = @This();
pub fn writeAll(p: *Printer, bytes: anytype) anyerror!void {
@@ -585,16 +586,17 @@ pub fn NewPrinter(
}
pub fn print(p: *Printer, str: anytype) void {
- switch (@TypeOf(str)) {
+ const StringType = @TypeOf(str);
+ switch (comptime StringType) {
comptime_int, u16, u8 => {
- p.writer.print(@TypeOf(str), str);
+ p.writer.print(StringType, str);
},
[6]u8 => {
const span = std.mem.span(&str);
p.writer.print(@TypeOf(span), span);
},
else => {
- p.writer.print(@TypeOf(str), str);
+ p.writer.print(StringType, str);
},
}
}
@@ -670,12 +672,20 @@ pub fn NewPrinter(
if (import.items.len > 0) {
p.print("var ");
p.print("{ ");
+
if (!import.is_single_line) {
p.print("\n");
p.options.indent += 1;
p.printIndent();
}
+ if (import.default_name) |default_name| {
+ p.print("default:");
+ p.printSpaceBeforeIdentifier();
+ p.printSymbol(default_name.ref.?);
+ p.print(", ");
+ }
+
for (import.items) |item, i| {
if (i > 0) {
p.print(",");
@@ -687,14 +697,7 @@ pub fn NewPrinter(
}
}
- const name = p.renamer.nameForSymbol(item.name.ref.?);
- p.printIdentifier(name);
-
- if (!strings.eql(name, item.alias)) {
- p.print(" : ");
- p.printSpace();
- p.printClauseAlias(item.alias);
- }
+ p.printClauseItemAs(item, true);
}
if (!import.is_single_line) {
@@ -1440,6 +1443,32 @@ pub fn NewPrinter(
p.print(quote);
}
+ fn printClauseItem(p: *Printer, item: js_ast.ClauseItem) void {
+ return printClauseItemAs(p, item, false);
+ }
+
+ fn printClauseItemAs(p: *Printer, item: js_ast.ClauseItem, comptime as_variable: bool) void {
+ const name = p.renamer.nameForSymbol(item.name.ref.?);
+
+ if (comptime !as_variable) {
+ p.printIdentifier(name);
+
+ if (!strings.eql(name, item.alias)) {
+ p.print(" as");
+ p.printSpace();
+ p.printClauseAlias(item.alias);
+ }
+ } else {
+ p.printClauseAlias(item.alias);
+
+ if (!strings.eql(name, item.alias)) {
+ p.print(":");
+ p.printSpace();
+ p.printIdentifier(name);
+ }
+ }
+ }
+
pub inline fn canPrintIdentifier(_: *Printer, name: string) bool {
if (comptime is_json) return false;
@@ -3214,7 +3243,7 @@ pub fn NewPrinter(
p.printSpace();
}
- for (s.items) |*item, i| {
+ for (s.items) |item, i| {
if (i != 0) {
p.print(",");
if (s.is_single_line) {
@@ -3227,13 +3256,7 @@ pub fn NewPrinter(
p.printIndent();
}
- const name = p.renamer.nameForSymbol(item.name.ref.?);
- p.printIdentifier(name);
- if (!strings.eql(name, item.alias)) {
- p.print(" as");
- p.printSpace();
- p.printClauseAlias(item.alias);
- }
+ p.printClauseItem(item);
}
if (!s.is_single_line) {
@@ -3293,6 +3316,65 @@ pub fn NewPrinter(
}
p.printIndent();
p.printSpaceBeforeIdentifier();
+
+ const import_record = p.import_records[s.import_record_index];
+
+ if (comptime is_bun_platform) {
+ if (import_record.do_commonjs_transform_in_printer) {
+ assert(s.items.len > 0);
+
+ p.print("var {");
+ var symbol_counter: u32 = p.symbol_counter;
+
+ for (s.items) |item, i| {
+ if (i > 0) {
+ p.print(",");
+ }
+
+ p.print(item.original_name);
+ assert(item.original_name.len > 0);
+ p.print(":");
+ // this is unsound
+ // this is technical debt
+ // we need to handle symbol collisions for this
+ p.print("$eXp0rT_");
+ var buf: [16]u8 = undefined;
+ p.print(std.fmt.bufPrint(&buf, "{}", .{std.fmt.fmtSliceHexLower(&@bitCast([4]u8, symbol_counter))}) catch unreachable);
+ symbol_counter +|= 1;
+ }
+
+ p.print("}=import.meta.require(");
+ p.printQuotedUTF8(import_record.path.text, true);
+ p.print(")");
+ p.printSemicolonAfterStatement();
+ p.print("export {");
+
+ // reset symbol counter back
+ symbol_counter = p.symbol_counter;
+
+ for (s.items) |item, i| {
+ if (i > 0) {
+ p.print(",");
+ }
+
+ // this is unsound
+ // this is technical debt
+ // we need to handle symbol collisions for this
+ p.print("$eXp0rT_");
+ var buf: [16]u8 = undefined;
+ p.print(std.fmt.bufPrint(&buf, "{}", .{std.fmt.fmtSliceHexLower(&@bitCast([4]u8, symbol_counter))}) catch unreachable);
+ symbol_counter +|= 1;
+ p.print(" as ");
+ p.print(item.alias);
+ }
+
+ p.print("}");
+ p.printSemicolonAfterStatement();
+ p.symbol_counter = symbol_counter;
+ return;
+ }
+ }
+
p.print("export");
p.printSpace();
p.print("{");
@@ -3336,7 +3418,7 @@ pub fn NewPrinter(
p.printSpace();
p.print("from");
p.printSpace();
- p.printQuotedUTF8(p.import_records[s.import_record_index].path.text, false);
+ p.printQuotedUTF8(import_record.path.text, false);
p.printSemicolonAfterStatement();
},
.s_local => |s| {
@@ -3661,7 +3743,7 @@ pub fn NewPrinter(
return p.printBundledImport(record, s);
}
- if (record.wrap_with_to_module or record.path.is_disabled) {
+ if (record.do_commonjs_transform_in_printer or record.path.is_disabled) {
const require_ref = p.options.require_ref;
const module_id = record.module_id;
@@ -3703,13 +3785,7 @@ pub fn NewPrinter(
if (s.items.len > 0) {
p.print(", ");
for (s.items) |item, i| {
- p.print(item.alias);
- const name = p.renamer.nameForSymbol(item.name.ref.?);
-
- if (!strings.eql(name, item.alias)) {
- p.print(": ");
- p.printSymbol(item.name.ref.?);
- }
+ p.printClauseItemAs(item, true);
if (i < s.items.len - 1) {
p.print(", ");
@@ -3718,12 +3794,7 @@ pub fn NewPrinter(
}
} else {
for (s.items) |item, i| {
- p.print(item.alias);
- const name = p.renamer.nameForSymbol(item.name.ref.?);
- if (!strings.eql(name, item.alias)) {
- p.print(":");
- p.printSymbol(item.name.ref.?);
- }
+ p.printClauseItemAs(item, true);
if (i < s.items.len - 1) {
p.print(", ");
@@ -3817,7 +3888,7 @@ pub fn NewPrinter(
p.options.unindent();
}
- for (s.items) |*item, i| {
+ for (s.items) |item, i| {
if (i != 0) {
p.print(",");
if (s.is_single_line) {
@@ -3830,14 +3901,7 @@ pub fn NewPrinter(
p.printIndent();
}
- p.printClauseAlias(item.alias);
- const name = p.renamer.nameForSymbol(item.name.ref.?);
- if (!strings.eql(name, item.alias)) {
- p.printSpace();
- p.printSpaceBeforeIdentifier();
- p.print("as ");
- p.printIdentifier(name);
- }
+ p.printClauseItem(item);
}
if (!s.is_single_line) {
diff --git a/src/linker.zig b/src/linker.zig
index 449367b00..e67339216 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -272,7 +272,7 @@ pub const Linker = struct {
if (JSC.DisabledModule.has(import_record.path.text)) {
import_record.path.is_disabled = true;
- import_record.wrap_with_to_module = true;
+ import_record.do_commonjs_transform_in_printer = true;
continue;
}
@@ -483,22 +483,22 @@ pub const Linker = struct {
import_path_format,
) catch continue;
- if (comptime !supports_dynamic_require) {
- // If we're importing a CommonJS module as ESM
- // We need to do the following transform:
- // import React from 'react';
- // =>
- // import {_require} from 'RUNTIME_IMPORTS';
- // import * as react_module from 'react';
- // var React = _require(react_module).default;
- // UNLESS it's a namespace import
- // If it's a namespace import, assume it's safe.
- // We can do this in the printer instead of creating a bunch of AST nodes here.
- // But we need to at least tell the printer that this needs to happen.
- if (loader != .napi and resolved_import.shouldAssumeCommonJS(import_record.kind)) {
- import_record.wrap_with_to_module = true;
- import_record.module_id = @truncate(u32, std.hash.Wyhash.hash(0, path.pretty));
-
+ // If we're importing a CommonJS module as ESM
+ // We need to do the following transform:
+ // import React from 'react';
+ // =>
+ // import {_require} from 'RUNTIME_IMPORTS';
+ // import * as react_module from 'react';
+ // var React = _require(react_module).default;
+ // UNLESS it's a namespace import
+ // If it's a namespace import, assume it's safe.
+ // We can do this in the printer instead of creating a bunch of AST nodes here.
+ // But we need to at least tell the printer that this needs to happen.
+ if (loader != .napi and resolved_import.shouldAssumeCommonJS(import_record.kind)) {
+ import_record.do_commonjs_transform_in_printer = true;
+ import_record.module_id = @truncate(u32, std.hash.Wyhash.hash(0, path.pretty));
+
+ if (comptime !supports_dynamic_require) {
result.ast.needs_runtime = true;
needs_require = true;
}