mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
@@ -31,7 +31,8 @@
|
|||||||
"test/bundler/native-plugin.test.ts", // parser doesn't handle import metadata
|
"test/bundler/native-plugin.test.ts", // parser doesn't handle import metadata
|
||||||
"test/bundler/transpiler/with-statement-works.js", // parser doesn't allow `with` statement
|
"test/bundler/transpiler/with-statement-works.js", // parser doesn't allow `with` statement
|
||||||
"test/js/node/module/extensions-fixture", // these files are not meant to be linted
|
"test/js/node/module/extensions-fixture", // these files are not meant to be linted
|
||||||
"test/cli/run/module-type-fixture"
|
"test/cli/run/module-type-fixture",
|
||||||
|
"test/bundler/transpiler/with-statement-works.js" // parser doesn't allow `with` statement
|
||||||
],
|
],
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,181 +0,0 @@
|
|||||||
#include "JSCommonJSExtensions.h"
|
|
||||||
#include "ZigGlobalObject.h"
|
|
||||||
|
|
||||||
namespace Bun {
|
|
||||||
using namespace JSC;
|
|
||||||
|
|
||||||
const JSC::ClassInfo JSCommonJSExtensions::s_info = { "CommonJSExtensions"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCommonJSExtensions) };
|
|
||||||
|
|
||||||
// These functions are implemented as no-ops because it doesn't seem like any
|
|
||||||
// projects call them directly. They are defined separately so that assigning
|
|
||||||
// one to the other can be detected and use the corresponding loader.
|
|
||||||
JSC_DEFINE_HOST_FUNCTION(jsLoaderJS, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
||||||
{
|
|
||||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
|
||||||
throwTypeError(globalObject, scope, "Calling Module._extensions[\".js\"] directly is not implemented."_s);
|
|
||||||
return JSValue::encode({});
|
|
||||||
}
|
|
||||||
JSC_DEFINE_HOST_FUNCTION(jsLoaderJSON, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
||||||
{
|
|
||||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
|
||||||
throwTypeError(globalObject, scope, "Calling Module._extensions[\".json\"] directly is not implemented."_s);
|
|
||||||
return JSValue::encode({});
|
|
||||||
}
|
|
||||||
JSC_DEFINE_HOST_FUNCTION(jsLoaderNode, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
||||||
{
|
|
||||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
|
||||||
throwTypeError(globalObject, scope, "Calling Module._extensions[\".node\"] directly is not implemented."_s);
|
|
||||||
return JSValue::encode({});
|
|
||||||
}
|
|
||||||
JSC_DEFINE_HOST_FUNCTION(jsLoaderTS, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
|
||||||
{
|
|
||||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
|
||||||
throwTypeError(globalObject, scope, "Calling Module._extensions[\".ts\"] directly is not implemented."_s);
|
|
||||||
return JSValue::encode({});
|
|
||||||
}
|
|
||||||
|
|
||||||
void JSCommonJSExtensions::finishCreation(JSC::VM& vm)
|
|
||||||
{
|
|
||||||
Base::finishCreation(vm);
|
|
||||||
ASSERT(inherits(info()));
|
|
||||||
|
|
||||||
Zig::GlobalObject* global = defaultGlobalObject(globalObject());
|
|
||||||
JSC::JSFunction* fnLoadJS = JSC::JSFunction::create(
|
|
||||||
vm,
|
|
||||||
global,
|
|
||||||
2,
|
|
||||||
""_s,
|
|
||||||
jsLoaderJS,
|
|
||||||
JSC::ImplementationVisibility::Public,
|
|
||||||
JSC::Intrinsic::NoIntrinsic,
|
|
||||||
JSC::callHostFunctionAsConstructor);
|
|
||||||
JSC::JSFunction* fnLoadJSON = JSC::JSFunction::create(
|
|
||||||
vm,
|
|
||||||
global,
|
|
||||||
2,
|
|
||||||
""_s,
|
|
||||||
jsLoaderJSON,
|
|
||||||
JSC::ImplementationVisibility::Public,
|
|
||||||
JSC::Intrinsic::NoIntrinsic,
|
|
||||||
JSC::callHostFunctionAsConstructor);
|
|
||||||
JSC::JSFunction* fnLoadNode = JSC::JSFunction::create(
|
|
||||||
vm,
|
|
||||||
global,
|
|
||||||
2,
|
|
||||||
""_s,
|
|
||||||
jsLoaderNode,
|
|
||||||
JSC::ImplementationVisibility::Public,
|
|
||||||
JSC::Intrinsic::NoIntrinsic,
|
|
||||||
JSC::callHostFunctionAsConstructor);
|
|
||||||
JSC::JSFunction* fnLoadTS = JSC::JSFunction::create(
|
|
||||||
vm,
|
|
||||||
global,
|
|
||||||
2,
|
|
||||||
""_s,
|
|
||||||
jsLoaderTS,
|
|
||||||
JSC::ImplementationVisibility::Public,
|
|
||||||
JSC::Intrinsic::NoIntrinsic,
|
|
||||||
JSC::callHostFunctionAsConstructor);
|
|
||||||
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".js"_s), fnLoadJS, 0);
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".json"_s), fnLoadJSON, 0);
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".node"_s), fnLoadNode, 0);
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".ts"_s), fnLoadTS, 0);
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".cts"_s), fnLoadTS, 0);
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".mjs"_s), fnLoadJS, 0);
|
|
||||||
this->putDirect(vm, JSC::Identifier::fromString(vm, ".mts"_s), fnLoadTS, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void NodeModuleModule__onRequireExtensionModify(
|
|
||||||
Zig::GlobalObject* globalObject,
|
|
||||||
const BunString* key,
|
|
||||||
uint32_t kind,
|
|
||||||
JSC::JSValue value);
|
|
||||||
|
|
||||||
void onAssign(Zig::GlobalObject* globalObject, JSC::PropertyName propertyName, JSC::JSValue value)
|
|
||||||
{
|
|
||||||
if (propertyName.isSymbol()) return;
|
|
||||||
auto* name = propertyName.publicName();
|
|
||||||
if (!name->startsWith("."_s)) return;
|
|
||||||
BunString ext = Bun::toString(name);
|
|
||||||
uint32_t kind = 0;
|
|
||||||
if (value.isCallable()) {
|
|
||||||
JSC::CallData callData = JSC::getCallData(value);
|
|
||||||
if (callData.type == JSC::CallData::Type::Native) {
|
|
||||||
auto* untaggedPtr = callData.native.function.untaggedPtr();
|
|
||||||
if (untaggedPtr == &jsLoaderJS) {
|
|
||||||
kind = 1;
|
|
||||||
} else if (untaggedPtr == &jsLoaderJSON) {
|
|
||||||
kind = 2;
|
|
||||||
} else if (untaggedPtr == &jsLoaderNode) {
|
|
||||||
kind = 3;
|
|
||||||
} else if (untaggedPtr == &jsLoaderTS) {
|
|
||||||
kind = 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kind = -1;
|
|
||||||
}
|
|
||||||
NodeModuleModule__onRequireExtensionModify(globalObject, &ext, kind, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JSCommonJSExtensions::defineOwnProperty(JSC::JSObject* object, JSC::JSGlobalObject* globalObject, JSC::PropertyName propertyName, const JSC::PropertyDescriptor& descriptor, bool shouldThrow)
|
|
||||||
{
|
|
||||||
JSValue value = descriptor.value();
|
|
||||||
if (value) {
|
|
||||||
onAssign(defaultGlobalObject(globalObject), propertyName, value);
|
|
||||||
} else {
|
|
||||||
onAssign(defaultGlobalObject(globalObject), propertyName, JSC::jsUndefined());
|
|
||||||
}
|
|
||||||
return Base::defineOwnProperty(object, globalObject, propertyName, descriptor, shouldThrow);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JSCommonJSExtensions::put(JSC::JSCell* cell, JSC::JSGlobalObject* globalObject, JSC::PropertyName propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot)
|
|
||||||
{
|
|
||||||
onAssign(defaultGlobalObject(globalObject), propertyName, value);
|
|
||||||
return Base::put(cell, globalObject, propertyName, value, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JSCommonJSExtensions::deleteProperty(JSC::JSCell* cell, JSC::JSGlobalObject* globalObject, JSC::PropertyName propertyName, JSC::DeletePropertySlot& slot)
|
|
||||||
{
|
|
||||||
bool deleted = Base::deleteProperty(cell, globalObject, propertyName, slot);
|
|
||||||
if (deleted) {
|
|
||||||
onAssign(defaultGlobalObject(globalObject), propertyName, JSC::jsUndefined());
|
|
||||||
}
|
|
||||||
return deleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" uint32_t JSCommonJSExtensions__appendFunction(Zig::GlobalObject* globalObject, JSC::JSValue value)
|
|
||||||
{
|
|
||||||
JSCommonJSExtensions* extensions = globalObject->lazyRequireExtensionsObject();
|
|
||||||
extensions->m_registeredFunctions.append(JSC::WriteBarrier<Unknown>());
|
|
||||||
extensions->m_registeredFunctions.last().set(globalObject->vm(), extensions, value);
|
|
||||||
return extensions->m_registeredFunctions.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void JSCommonJSExtensions__setFunction(Zig::GlobalObject* globalObject, uint32_t index, JSC::JSValue value)
|
|
||||||
{
|
|
||||||
JSCommonJSExtensions* extensions = globalObject->lazyRequireExtensionsObject();
|
|
||||||
extensions->m_registeredFunctions[index].set(globalObject->vm(), globalObject, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" uint32_t JSCommonJSExtensions__swapRemove(Zig::GlobalObject* globalObject, uint32_t index)
|
|
||||||
{
|
|
||||||
JSCommonJSExtensions* extensions = globalObject->lazyRequireExtensionsObject();
|
|
||||||
ASSERT(extensions->m_registeredFunctions.size() > 0);
|
|
||||||
if (extensions->m_registeredFunctions.size() == 1) {
|
|
||||||
extensions->m_registeredFunctions.clear();
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
ASSERT(index < extensions->m_registeredFunctions.size());
|
|
||||||
if (index < (extensions->m_registeredFunctions.size() - 1)) {
|
|
||||||
JSValue last = extensions->m_registeredFunctions.takeLast().get();
|
|
||||||
extensions->m_registeredFunctions[index].set(globalObject->vm(), globalObject, last);
|
|
||||||
return extensions->m_registeredFunctions.size();
|
|
||||||
} else {
|
|
||||||
extensions->m_registeredFunctions.removeLast();
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Bun
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "root.h"
|
|
||||||
#include "headers-handwritten.h"
|
|
||||||
#include "BunClientData.h"
|
|
||||||
|
|
||||||
namespace Bun {
|
|
||||||
|
|
||||||
// require.extensions & Module._extensions
|
|
||||||
class JSCommonJSExtensions : public JSC::JSDestructibleObject {
|
|
||||||
public:
|
|
||||||
using Base = JSC::JSDestructibleObject;
|
|
||||||
static constexpr unsigned StructureFlags = Base::StructureFlags | JSC::OverridesPut;
|
|
||||||
~JSCommonJSExtensions();
|
|
||||||
|
|
||||||
WTF::Vector<JSC::WriteBarrier<JSC::Unknown>> m_registeredFunctions;
|
|
||||||
|
|
||||||
static JSCommonJSExtensions* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
|
|
||||||
{
|
|
||||||
JSCommonJSExtensions* ptr = new (NotNull, JSC::allocateCell<JSCommonJSExtensions>(vm)) JSCommonJSExtensions(vm, structure);
|
|
||||||
ptr->finishCreation(vm);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_INFO;
|
|
||||||
|
|
||||||
template<typename, JSC::SubspaceAccess mode>
|
|
||||||
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
|
|
||||||
{
|
|
||||||
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
|
|
||||||
return nullptr;
|
|
||||||
return WebCore::subspaceForImpl<JSCommonJSExtensions, WebCore::UseCustomHeapCellType::No>(
|
|
||||||
vm,
|
|
||||||
[](auto& spaces) { return spaces.m_clientSubspaceForJSCommonJSExtensions.get(); },
|
|
||||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForJSCommonJSExtensions = std::forward<decltype(space)>(space); },
|
|
||||||
[](auto& spaces) { return spaces.m_subspaceForJSCommonJSExtensions.get(); },
|
|
||||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForJSCommonJSExtensions = std::forward<decltype(space)>(space); });
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
|
|
||||||
{
|
|
||||||
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static bool defineOwnProperty(JSC::JSObject*, JSC::JSGlobalObject*, JSC::PropertyName, const JSC::PropertyDescriptor&, bool shouldThrow);
|
|
||||||
static bool put(JSC::JSCell*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::JSValue, JSC::PutPropertySlot&);
|
|
||||||
static bool deleteProperty(JSC::JSCell*, JSC::JSGlobalObject*, JSC::PropertyName, JSC::DeletePropertySlot&);
|
|
||||||
|
|
||||||
private:
|
|
||||||
JSCommonJSExtensions(JSC::VM& vm, JSC::Structure* structure)
|
|
||||||
: Base(vm, structure)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void finishCreation(JSC::VM&);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Bun
|
|
||||||
@@ -76,7 +76,6 @@
|
|||||||
#include "wtf/NakedPtr.h"
|
#include "wtf/NakedPtr.h"
|
||||||
#include "wtf/URL.h"
|
#include "wtf/URL.h"
|
||||||
#include "wtf/text/StringImpl.h"
|
#include "wtf/text/StringImpl.h"
|
||||||
#include "JSCommonJSExtensions.h"
|
|
||||||
|
|
||||||
extern "C" bool Bun__isBunMain(JSC::JSGlobalObject* global, const BunString*);
|
extern "C" bool Bun__isBunMain(JSC::JSGlobalObject* global, const BunString*);
|
||||||
|
|
||||||
@@ -299,31 +298,12 @@ JSC_DEFINE_CUSTOM_SETTER(jsRequireCacheSetter,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_DEFINE_CUSTOM_GETTER(jsRequireExtensionsGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
|
||||||
{
|
|
||||||
Zig::GlobalObject* thisObject = jsCast<Zig::GlobalObject*>(globalObject);
|
|
||||||
return JSValue::encode(thisObject->lazyRequireExtensionsObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
JSC_DEFINE_CUSTOM_SETTER(jsRequireExtensionsSetter,
|
|
||||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
|
||||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
|
||||||
{
|
|
||||||
JSObject* thisObject = jsDynamicCast<JSObject*>(JSValue::decode(thisValue));
|
|
||||||
if (!thisObject)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
thisObject->putDirect(globalObject->vm(), propertyName, JSValue::decode(value), 0);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const HashTableValue RequireResolveFunctionPrototypeValues[] = {
|
static const HashTableValue RequireResolveFunctionPrototypeValues[] = {
|
||||||
{ "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } },
|
{ "paths"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, requireResolvePathsFunction, 1 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const HashTableValue RequireFunctionPrototypeValues[] = {
|
static const HashTableValue RequireFunctionPrototypeValues[] = {
|
||||||
{ "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsRequireCacheGetter, jsRequireCacheSetter } },
|
{ "cache"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsRequireCacheGetter, jsRequireCacheSetter } },
|
||||||
{ "extensions"_s, static_cast<unsigned>(JSC::PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, jsRequireExtensionsGetter, jsRequireExtensionsSetter } },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Structure* RequireFunctionPrototype::createStructure(
|
Structure* RequireFunctionPrototype::createStructure(
|
||||||
@@ -386,6 +366,13 @@ void RequireFunctionPrototype::finishCreation(JSC::VM& vm)
|
|||||||
JSC::Identifier::fromString(vm, "main"_s),
|
JSC::Identifier::fromString(vm, "main"_s),
|
||||||
JSC::GetterSetter::create(vm, globalObject, requireDotMainFunction, requireDotMainFunction),
|
JSC::GetterSetter::create(vm, globalObject, requireDotMainFunction, requireDotMainFunction),
|
||||||
PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
|
PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
|
||||||
|
|
||||||
|
auto extensions = constructEmptyObject(globalObject);
|
||||||
|
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".js"_s), jsBoolean(true), 0);
|
||||||
|
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".json"_s), jsBoolean(true), 0);
|
||||||
|
extensions->putDirect(vm, JSC::Identifier::fromString(vm, ".node"_s), jsBoolean(true), 0);
|
||||||
|
|
||||||
|
this->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), extensions, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_DEFINE_CUSTOM_GETTER(getterFilename, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
JSC_DEFINE_CUSTOM_GETTER(getterFilename, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||||
@@ -1164,6 +1151,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
|
|||||||
// This is always a new JSCommonJSModule object; cast cannot fail.
|
// This is always a new JSCommonJSModule object; cast cannot fail.
|
||||||
JSCommonJSModule* child = jsCast<JSCommonJSModule*>(callframe->uncheckedArgument(1));
|
JSCommonJSModule* child = jsCast<JSCommonJSModule*>(callframe->uncheckedArgument(1));
|
||||||
|
|
||||||
|
BunString specifierStr = Bun::toString(specifier);
|
||||||
BunString referrerStr = Bun::toString(referrer);
|
BunString referrerStr = Bun::toString(referrer);
|
||||||
BunString typeAttributeStr = { BunStringTag::Dead };
|
BunString typeAttributeStr = { BunStringTag::Dead };
|
||||||
String typeAttribute = String();
|
String typeAttribute = String();
|
||||||
@@ -1194,7 +1182,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
|
|||||||
globalObject,
|
globalObject,
|
||||||
child,
|
child,
|
||||||
specifierValue,
|
specifierValue,
|
||||||
specifier,
|
&specifierStr,
|
||||||
&referrerStr,
|
&referrerStr,
|
||||||
LIKELY(typeAttribute.isEmpty())
|
LIKELY(typeAttribute.isEmpty())
|
||||||
? nullptr
|
? nullptr
|
||||||
|
|||||||
@@ -37,8 +37,6 @@
|
|||||||
#include "JSCommonJSModule.h"
|
#include "JSCommonJSModule.h"
|
||||||
#include "../modules/_NativeModule.h"
|
#include "../modules/_NativeModule.h"
|
||||||
|
|
||||||
#include "JSCommonJSExtensions.h"
|
|
||||||
|
|
||||||
namespace Bun {
|
namespace Bun {
|
||||||
using namespace JSC;
|
using namespace JSC;
|
||||||
using namespace Zig;
|
using namespace Zig;
|
||||||
@@ -569,39 +567,11 @@ JSValue resolveAndFetchBuiltinModule(
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void evaluateCommonJSCustomExtension(
|
|
||||||
Zig::GlobalObject* globalObject,
|
|
||||||
JSCommonJSModule* target,
|
|
||||||
String filename,
|
|
||||||
JSValue filenameValue,
|
|
||||||
uint32_t extensionIndex)
|
|
||||||
{
|
|
||||||
auto& vm = globalObject->vm();
|
|
||||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
|
||||||
Bun::JSCommonJSExtensions* extensions = globalObject->lazyRequireExtensionsObject();
|
|
||||||
JSValue extension = extensions->m_registeredFunctions[extensionIndex].get();
|
|
||||||
|
|
||||||
if (!extension || !extension.isCallable()) {
|
|
||||||
throwTypeError(globalObject, scope, makeString("require.extension is not a function"_s));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JSC::CallData callData = JSC::getCallData(extension.asCell());
|
|
||||||
if (callData.type == JSC::CallData::Type::None) {
|
|
||||||
throwTypeError(globalObject, scope, makeString("require.extension is not a function"_s));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MarkedArgumentBuffer arguments;
|
|
||||||
arguments.append(target);
|
|
||||||
arguments.append(filenameValue);
|
|
||||||
JSC::profiledCall(globalObject, ProfilingReason::API, extension, callData, target, arguments);
|
|
||||||
RETURN_IF_EXCEPTION(scope, );
|
|
||||||
}
|
|
||||||
|
|
||||||
JSValue fetchCommonJSModule(
|
JSValue fetchCommonJSModule(
|
||||||
Zig::GlobalObject* globalObject,
|
Zig::GlobalObject* globalObject,
|
||||||
JSCommonJSModule* target,
|
JSCommonJSModule* target,
|
||||||
JSValue specifierValue,
|
JSValue specifierValue,
|
||||||
String specifierWtfString,
|
BunString* specifier,
|
||||||
BunString* referrer,
|
BunString* referrer,
|
||||||
BunString* typeAttribute)
|
BunString* typeAttribute)
|
||||||
{
|
{
|
||||||
@@ -614,15 +584,13 @@ JSValue fetchCommonJSModule(
|
|||||||
ErrorableResolvedSource* res = &resValue;
|
ErrorableResolvedSource* res = &resValue;
|
||||||
ResolvedSourceCodeHolder sourceCodeHolder(res);
|
ResolvedSourceCodeHolder sourceCodeHolder(res);
|
||||||
|
|
||||||
BunString specifier = Bun::toString(specifierWtfString);
|
|
||||||
|
|
||||||
bool wasModuleMock = false;
|
bool wasModuleMock = false;
|
||||||
|
|
||||||
// When "bun test" is enabled, allow users to override builtin modules
|
// When "bun test" is enabled, allow users to override builtin modules
|
||||||
// This is important for being able to trivially mock things like the filesystem.
|
// This is important for being able to trivially mock things like the filesystem.
|
||||||
if (isBunTest) {
|
if (isBunTest) {
|
||||||
if (JSC::JSValue virtualModuleResult = Bun::runVirtualModule(globalObject, &specifier, wasModuleMock)) {
|
if (JSC::JSValue virtualModuleResult = Bun::runVirtualModule(globalObject, specifier, wasModuleMock)) {
|
||||||
JSValue promiseOrCommonJSModule = handleVirtualModuleResult<true>(globalObject, virtualModuleResult, res, &specifier, referrer, wasModuleMock, target);
|
JSValue promiseOrCommonJSModule = handleVirtualModuleResult<true>(globalObject, virtualModuleResult, res, specifier, referrer, wasModuleMock, target);
|
||||||
RETURN_IF_EXCEPTION(scope, {});
|
RETURN_IF_EXCEPTION(scope, {});
|
||||||
|
|
||||||
// If we assigned module.exports to the virtual module, we're done here.
|
// If we assigned module.exports to the virtual module, we're done here.
|
||||||
@@ -638,7 +606,7 @@ JSValue fetchCommonJSModule(
|
|||||||
RELEASE_AND_RETURN(scope, JSValue {});
|
RELEASE_AND_RETURN(scope, JSValue {});
|
||||||
}
|
}
|
||||||
case JSPromise::Status::Pending: {
|
case JSPromise::Status::Pending: {
|
||||||
JSC::throwTypeError(globalObject, scope, makeString("require() async module \""_s, specifierWtfString, "\" is unsupported. use \"await import()\" instead."_s));
|
JSC::throwTypeError(globalObject, scope, makeString("require() async module \""_s, specifier->toWTFString(BunString::ZeroCopy), "\" is unsupported. use \"await import()\" instead."_s));
|
||||||
RELEASE_AND_RETURN(scope, JSValue {});
|
RELEASE_AND_RETURN(scope, JSValue {});
|
||||||
}
|
}
|
||||||
case JSPromise::Status::Fulfilled: {
|
case JSPromise::Status::Fulfilled: {
|
||||||
@@ -657,7 +625,7 @@ JSValue fetchCommonJSModule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto builtin = fetchBuiltinModuleWithoutResolution(globalObject, &specifier, res)) {
|
if (auto builtin = fetchBuiltinModuleWithoutResolution(globalObject, specifier, res)) {
|
||||||
if (!res->success) {
|
if (!res->success) {
|
||||||
RELEASE_AND_RETURN(scope, builtin);
|
RELEASE_AND_RETURN(scope, builtin);
|
||||||
}
|
}
|
||||||
@@ -668,8 +636,8 @@ JSValue fetchCommonJSModule(
|
|||||||
|
|
||||||
// When "bun test" is NOT enabled, disable users from overriding builtin modules
|
// When "bun test" is NOT enabled, disable users from overriding builtin modules
|
||||||
if (!isBunTest) {
|
if (!isBunTest) {
|
||||||
if (JSC::JSValue virtualModuleResult = Bun::runVirtualModule(globalObject, &specifier, wasModuleMock)) {
|
if (JSC::JSValue virtualModuleResult = Bun::runVirtualModule(globalObject, specifier, wasModuleMock)) {
|
||||||
JSValue promiseOrCommonJSModule = handleVirtualModuleResult<true>(globalObject, virtualModuleResult, res, &specifier, referrer, wasModuleMock, target);
|
JSValue promiseOrCommonJSModule = handleVirtualModuleResult<true>(globalObject, virtualModuleResult, res, specifier, referrer, wasModuleMock, target);
|
||||||
RETURN_IF_EXCEPTION(scope, {});
|
RETURN_IF_EXCEPTION(scope, {});
|
||||||
|
|
||||||
// If we assigned module.exports to the virtual module, we're done here.
|
// If we assigned module.exports to the virtual module, we're done here.
|
||||||
@@ -685,7 +653,7 @@ JSValue fetchCommonJSModule(
|
|||||||
RELEASE_AND_RETURN(scope, JSValue {});
|
RELEASE_AND_RETURN(scope, JSValue {});
|
||||||
}
|
}
|
||||||
case JSPromise::Status::Pending: {
|
case JSPromise::Status::Pending: {
|
||||||
JSC::throwTypeError(globalObject, scope, makeString("require() async module \""_s, specifierWtfString, "\" is unsupported. use \"await import()\" instead."_s));
|
JSC::throwTypeError(globalObject, scope, makeString("require() async module \""_s, specifier->toWTFString(BunString::ZeroCopy), "\" is unsupported. use \"await import()\" instead."_s));
|
||||||
RELEASE_AND_RETURN(scope, JSValue {});
|
RELEASE_AND_RETURN(scope, JSValue {});
|
||||||
}
|
}
|
||||||
case JSPromise::Status::Fulfilled: {
|
case JSPromise::Status::Fulfilled: {
|
||||||
@@ -721,9 +689,9 @@ JSValue fetchCommonJSModule(
|
|||||||
RELEASE_AND_RETURN(scope, jsNumber(-1));
|
RELEASE_AND_RETURN(scope, jsNumber(-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
Bun__transpileFile(bunVM, globalObject, &specifier, referrer, typeAttribute, res, false, true);
|
Bun__transpileFile(bunVM, globalObject, specifier, referrer, typeAttribute, res, false);
|
||||||
if (res->success && res->result.value.isCommonJSModule) {
|
if (res->success && res->result.value.isCommonJSModule) {
|
||||||
target->evaluate(globalObject, specifierWtfString, res->result.value);
|
target->evaluate(globalObject, specifier->toWTFString(BunString::ZeroCopy), res->result.value);
|
||||||
RETURN_IF_EXCEPTION(scope, {});
|
RETURN_IF_EXCEPTION(scope, {});
|
||||||
RELEASE_AND_RETURN(scope, target);
|
RELEASE_AND_RETURN(scope, target);
|
||||||
}
|
}
|
||||||
@@ -765,10 +733,6 @@ JSValue fetchCommonJSModule(
|
|||||||
target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, 0);
|
target->putDirect(vm, WebCore::clientData(vm)->builtinNames().exportsPublicName(), value, 0);
|
||||||
target->hasEvaluated = true;
|
target->hasEvaluated = true;
|
||||||
RELEASE_AND_RETURN(scope, target);
|
RELEASE_AND_RETURN(scope, target);
|
||||||
} else if (res->result.value.tag == SyntheticModuleType::CommonJSCustomExtension) {
|
|
||||||
evaluateCommonJSCustomExtension(globalObject, target, specifierWtfString, specifierValue, res->result.value.cjsCustomExtensionIndex);
|
|
||||||
RETURN_IF_EXCEPTION(scope, {});
|
|
||||||
RELEASE_AND_RETURN(scope, target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto&& provider = Zig::SourceProvider::create(globalObject, res->result.value);
|
auto&& provider = Zig::SourceProvider::create(globalObject, res->result.value);
|
||||||
@@ -896,12 +860,12 @@ static JSValue fetchESMSourceCode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (allowPromise) {
|
if constexpr (allowPromise) {
|
||||||
auto* pendingCtx = Bun__transpileFile(bunVM, globalObject, specifier, referrer, typeAttribute, res, true, false);
|
auto* pendingCtx = Bun__transpileFile(bunVM, globalObject, specifier, referrer, typeAttribute, res, true);
|
||||||
if (pendingCtx) {
|
if (pendingCtx) {
|
||||||
return pendingCtx;
|
return pendingCtx;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Bun__transpileFile(bunVM, globalObject, specifier, referrer, typeAttribute, res, false, false);
|
Bun__transpileFile(bunVM, globalObject, specifier, referrer, typeAttribute, res, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res->success && res->result.value.isCommonJSModule) {
|
if (res->success && res->result.value.isCommonJSModule) {
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ JSValue fetchCommonJSModule(
|
|||||||
Zig::GlobalObject* globalObject,
|
Zig::GlobalObject* globalObject,
|
||||||
JSCommonJSModule* moduleObject,
|
JSCommonJSModule* moduleObject,
|
||||||
JSValue specifierValue,
|
JSValue specifierValue,
|
||||||
String specifier,
|
BunString* specifier,
|
||||||
BunString* referrer,
|
BunString* referrer,
|
||||||
BunString* typeAttribute);
|
BunString* typeAttribute);
|
||||||
|
|
||||||
|
|||||||
@@ -81,154 +81,3 @@ pub fn _stat(path: []const u8) i32 {
|
|||||||
.directory => 1, // Returns 1 for directories.
|
.directory => 1, // Returns 1 for directories.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const CustomLoader = union(enum) {
|
|
||||||
loader: bun.options.Loader,
|
|
||||||
/// Retrieve via WriteBarrier in `global->lazyRequireExtensionsObject().get(index)`
|
|
||||||
custom: u32,
|
|
||||||
|
|
||||||
pub const Packed = enum(u32) {
|
|
||||||
const loader_start: u32 = std.math.maxInt(u32) - 4;
|
|
||||||
js = loader_start,
|
|
||||||
json = loader_start + 1,
|
|
||||||
napi = loader_start + 2,
|
|
||||||
ts = loader_start + 3,
|
|
||||||
/// custom
|
|
||||||
_,
|
|
||||||
|
|
||||||
pub fn pack(loader: CustomLoader) Packed {
|
|
||||||
return switch (loader) {
|
|
||||||
.loader => |basic| switch (basic) {
|
|
||||||
.js => .js,
|
|
||||||
.json => .json,
|
|
||||||
.napi => .napi,
|
|
||||||
.ts => .ts,
|
|
||||||
else => brk: {
|
|
||||||
bun.debugAssert(false);
|
|
||||||
break :brk .js;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.custom => |custom| @enumFromInt(custom),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unpack(self: Packed) CustomLoader {
|
|
||||||
return switch (self) {
|
|
||||||
.js => .{ .loader = .js },
|
|
||||||
.json => .{ .loader = .json },
|
|
||||||
.napi => .{ .loader = .napi },
|
|
||||||
.ts => .{ .loader = .ts },
|
|
||||||
_ => .{ .custom = @intFromEnum(self) },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
extern fn JSCommonJSExtensions__appendFunction(global: *JSC.JSGlobalObject, value: JSC.JSValue) u32;
|
|
||||||
extern fn JSCommonJSExtensions__setFunction(global: *JSC.JSGlobalObject, index: u32, value: JSC.JSValue) void;
|
|
||||||
/// Returns the index of the last value, which must have it's references updated to `index`
|
|
||||||
extern fn JSCommonJSExtensions__swapRemove(global: *JSC.JSGlobalObject, index: u32) u32;
|
|
||||||
|
|
||||||
// Memory management is complicated because JSValues are stored in gc-visitable
|
|
||||||
// WriteBarriers in C++ but the hash map for extensions is in Zig for flexibility.
|
|
||||||
fn onRequireExtensionModify(global: *JSC.JSGlobalObject, str: []const u8, kind: i32, value: JSC.JSValue) !void {
|
|
||||||
bun.assert(kind >= -1 and kind <= 4);
|
|
||||||
const vm = global.bunVM();
|
|
||||||
const list = &vm.commonjs_custom_extensions;
|
|
||||||
defer vm.transpiler.resolver.opts.extra_cjs_extensions = list.keys();
|
|
||||||
const is_built_in = bun.options.defaultLoaders.get(str) != null;
|
|
||||||
if (kind >= 0) {
|
|
||||||
const loader: CustomLoader = switch (kind) {
|
|
||||||
1 => .{ .loader = .js },
|
|
||||||
2 => .{ .loader = .json },
|
|
||||||
3 => .{ .loader = .napi },
|
|
||||||
4 => .{ .loader = .ts },
|
|
||||||
else => .{ .custom = undefined }, // to be filled in later
|
|
||||||
};
|
|
||||||
const gop = try list.getOrPut(bun.default_allocator, str);
|
|
||||||
if (!gop.found_existing) {
|
|
||||||
const dupe = try bun.default_allocator.dupe(u8, str);
|
|
||||||
errdefer bun.default_allocator.free(dupe);
|
|
||||||
gop.key_ptr.* = dupe;
|
|
||||||
if (is_built_in) {
|
|
||||||
vm.has_mutated_built_in_extensions += 1;
|
|
||||||
}
|
|
||||||
gop.value_ptr.* = .pack(switch (loader) {
|
|
||||||
.loader => loader,
|
|
||||||
.custom => .{
|
|
||||||
.custom = JSCommonJSExtensions__appendFunction(global, value),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const existing = gop.value_ptr.*.unpack();
|
|
||||||
if (existing == .custom and loader != .custom) {
|
|
||||||
swapRemoveExtension(vm, existing.custom);
|
|
||||||
}
|
|
||||||
gop.value_ptr.* = .pack(switch (loader) {
|
|
||||||
.loader => loader,
|
|
||||||
.custom => .{
|
|
||||||
.custom = if (existing == .custom) new: {
|
|
||||||
JSCommonJSExtensions__setFunction(global, existing.custom, value);
|
|
||||||
break :new existing.custom;
|
|
||||||
} else JSCommonJSExtensions__appendFunction(global, value),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (list.fetchSwapRemove(str)) |prev| {
|
|
||||||
bun.default_allocator.free(prev.key);
|
|
||||||
if (is_built_in) {
|
|
||||||
vm.has_mutated_built_in_extensions -= 1;
|
|
||||||
}
|
|
||||||
switch (prev.value.unpack()) {
|
|
||||||
.loader => {},
|
|
||||||
.custom => |index| swapRemoveExtension(vm, index),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn swapRemoveExtension(vm: *JSC.VirtualMachine, index: u32) void {
|
|
||||||
const last_index = JSCommonJSExtensions__swapRemove(vm.global, index);
|
|
||||||
if (last_index == index) return;
|
|
||||||
// Find and rewrite the last index to the new index.
|
|
||||||
// Since packed structs are sugar over the backing int, this code can use
|
|
||||||
// the simd path in the standard library search.
|
|
||||||
const find: u32 = @intFromEnum(CustomLoader.Packed.pack(.{ .custom = last_index }));
|
|
||||||
const values = vm.commonjs_custom_extensions.values();
|
|
||||||
const values_reinterpret = bun.reinterpretSlice(u32, values);
|
|
||||||
const i = std.mem.indexOfScalar(u32, values_reinterpret, find) orelse
|
|
||||||
return bun.debugAssert(false);
|
|
||||||
values[i] = .pack(.{ .custom = last_index });
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn findLongestRegisteredExtension(vm: *JSC.VirtualMachine, filename: []const u8) ?CustomLoader {
|
|
||||||
const basename = std.fs.path.basename(filename);
|
|
||||||
var next: usize = 0;
|
|
||||||
while (bun.strings.indexOfCharPos(basename, '.', next)) |i| {
|
|
||||||
next = i + 1;
|
|
||||||
if (i == 0) continue;
|
|
||||||
const ext = basename[i..];
|
|
||||||
if (vm.commonjs_custom_extensions.get(ext)) |value| {
|
|
||||||
return value.unpack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn onRequireExtensionModifyBinding(
|
|
||||||
global: *JSC.JSGlobalObject,
|
|
||||||
str: *const bun.String,
|
|
||||||
kind: i32,
|
|
||||||
value: JSC.JSValue,
|
|
||||||
) callconv(.c) void {
|
|
||||||
var sfa_state = std.heap.stackFallback(8192, bun.default_allocator);
|
|
||||||
const alloc = sfa_state.get();
|
|
||||||
const str_slice = str.toUTF8(alloc);
|
|
||||||
defer str_slice.deinit();
|
|
||||||
onRequireExtensionModify(global, str_slice.slice(), kind, value) catch |err| switch (err) {
|
|
||||||
error.OutOfMemory => bun.outOfMemory(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
comptime {
|
|
||||||
@export(&onRequireExtensionModifyBinding, .{ .name = "NodeModuleModule__onRequireExtensionModify" });
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,15 +13,13 @@ pub const ResolvedSource = extern struct {
|
|||||||
|
|
||||||
is_commonjs_module: bool = false,
|
is_commonjs_module: bool = false,
|
||||||
|
|
||||||
/// When .tag is .common_js_custom_extension, this is special-cased to hold
|
hash: u32 = 0,
|
||||||
/// the index of the extension, since the module is stored in a WriteBarrier.
|
|
||||||
cjs_custom_extension_index: u32 = 0,
|
|
||||||
|
|
||||||
allocator: ?*anyopaque = null,
|
allocator: ?*anyopaque = null,
|
||||||
|
|
||||||
jsvalue_for_export: JSValue = .zero,
|
jsvalue_for_export: JSValue = .zero,
|
||||||
|
|
||||||
tag: Tag = .javascript,
|
tag: Tag = Tag.javascript,
|
||||||
|
|
||||||
/// This is for source_code
|
/// This is for source_code
|
||||||
source_code_needs_deref: bool = true,
|
source_code_needs_deref: bool = true,
|
||||||
|
|||||||
@@ -2938,6 +2938,18 @@ void GlobalObject::finishCreation(VM& vm)
|
|||||||
init.set(crypto);
|
init.set(crypto);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_lazyRequireCacheObject.initLater(
|
||||||
|
[](const Initializer<JSObject>& init) {
|
||||||
|
JSC::VM& vm = init.vm;
|
||||||
|
JSC::JSGlobalObject* globalObject = init.owner;
|
||||||
|
|
||||||
|
auto* function = JSFunction::create(vm, globalObject, static_cast<JSC::FunctionExecutable*>(commonJSCreateRequireCacheCodeGenerator(vm)), globalObject);
|
||||||
|
|
||||||
|
NakedPtr<JSC::Exception> returnedException = nullptr;
|
||||||
|
auto result = JSC::profiledCall(globalObject, ProfilingReason::API, function, JSC::getCallData(function), globalObject, ArgList(), returnedException);
|
||||||
|
init.set(result.toObject(globalObject));
|
||||||
|
});
|
||||||
|
|
||||||
m_lazyTestModuleObject.initLater(
|
m_lazyTestModuleObject.initLater(
|
||||||
[](const Initializer<JSObject>& init) {
|
[](const Initializer<JSObject>& init) {
|
||||||
JSC::JSGlobalObject* globalObject = init.owner;
|
JSC::JSGlobalObject* globalObject = init.owner;
|
||||||
|
|||||||
@@ -56,13 +56,6 @@ class GlobalInternals;
|
|||||||
#include <js_native_api.h>
|
#include <js_native_api.h>
|
||||||
#include <node_api.h>
|
#include <node_api.h>
|
||||||
|
|
||||||
namespace Bun {
|
|
||||||
class JSCommonJSExtensions;
|
|
||||||
class InternalModuleRegistry;
|
|
||||||
class JSMockModule;
|
|
||||||
class JSMockFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace WebCore {
|
namespace WebCore {
|
||||||
class WorkerGlobalScope;
|
class WorkerGlobalScope;
|
||||||
class SubtleCrypto;
|
class SubtleCrypto;
|
||||||
@@ -269,7 +262,6 @@ public:
|
|||||||
JSObject* processBindingFs() const { return m_processBindingFs.getInitializedOnMainThread(this); }
|
JSObject* processBindingFs() const { return m_processBindingFs.getInitializedOnMainThread(this); }
|
||||||
|
|
||||||
JSObject* lazyRequireCacheObject() const { return m_lazyRequireCacheObject.getInitializedOnMainThread(this); }
|
JSObject* lazyRequireCacheObject() const { return m_lazyRequireCacheObject.getInitializedOnMainThread(this); }
|
||||||
Bun::JSCommonJSExtensions* lazyRequireExtensionsObject() const { return m_lazyRequireExtensionsObject.getInitializedOnMainThread(this); }
|
|
||||||
|
|
||||||
Structure* NodeVMGlobalObjectStructure() const { return m_cachedNodeVMGlobalObjectStructure.getInitializedOnMainThread(this); }
|
Structure* NodeVMGlobalObjectStructure() const { return m_cachedNodeVMGlobalObjectStructure.getInitializedOnMainThread(this); }
|
||||||
Structure* globalProxyStructure() const { return m_cachedGlobalProxyStructure.getInitializedOnMainThread(this); }
|
Structure* globalProxyStructure() const { return m_cachedGlobalProxyStructure.getInitializedOnMainThread(this); }
|
||||||
@@ -594,7 +586,6 @@ public:
|
|||||||
LazyProperty<JSGlobalObject, Structure> m_JSResizableOrGrowableSharedBufferSubclassStructure;
|
LazyProperty<JSGlobalObject, Structure> m_JSResizableOrGrowableSharedBufferSubclassStructure;
|
||||||
LazyProperty<JSGlobalObject, JSWeakMap> m_vmModuleContextMap;
|
LazyProperty<JSGlobalObject, JSWeakMap> m_vmModuleContextMap;
|
||||||
LazyProperty<JSGlobalObject, JSObject> m_lazyRequireCacheObject;
|
LazyProperty<JSGlobalObject, JSObject> m_lazyRequireCacheObject;
|
||||||
LazyProperty<JSGlobalObject, Bun::JSCommonJSExtensions> m_lazyRequireExtensionsObject;
|
|
||||||
LazyProperty<JSGlobalObject, JSObject> m_lazyTestModuleObject;
|
LazyProperty<JSGlobalObject, JSObject> m_lazyTestModuleObject;
|
||||||
LazyProperty<JSGlobalObject, JSObject> m_lazyPreloadTestModuleObject;
|
LazyProperty<JSGlobalObject, JSObject> m_lazyPreloadTestModuleObject;
|
||||||
LazyProperty<JSGlobalObject, JSObject> m_testMatcherUtilsObject;
|
LazyProperty<JSGlobalObject, JSObject> m_testMatcherUtilsObject;
|
||||||
|
|||||||
@@ -342,30 +342,30 @@ pub fn initialize(eval_mode: bool) void {
|
|||||||
JSCInitialize(
|
JSCInitialize(
|
||||||
std.os.environ.ptr,
|
std.os.environ.ptr,
|
||||||
std.os.environ.len,
|
std.os.environ.len,
|
||||||
onJSCInvalidEnvVar,
|
struct {
|
||||||
|
pub fn callback(name: [*]const u8, len: usize) callconv(.C) void {
|
||||||
|
Output.prettyErrorln(
|
||||||
|
\\<r><red>error<r><d>:<r> invalid JSC environment variable
|
||||||
|
\\
|
||||||
|
\\ <b>{s}<r>
|
||||||
|
\\
|
||||||
|
\\For a list of options, see this file:
|
||||||
|
\\
|
||||||
|
\\ https://github.com/oven-sh/webkit/blob/main/Source/JavaScriptCore/runtime/OptionsList.h
|
||||||
|
\\
|
||||||
|
\\Environment variables must be prefixed with "BUN_JSC_". This code runs before .env files are loaded, so those won't work here.
|
||||||
|
\\
|
||||||
|
\\Warning: options change between releases of Bun and WebKit without notice. This is not a stable API, you should not rely on it beyond debugging something, and it may be removed entirely in a future version of Bun.
|
||||||
|
,
|
||||||
|
.{name[0..len]},
|
||||||
|
);
|
||||||
|
bun.Global.exit(1);
|
||||||
|
}
|
||||||
|
}.callback,
|
||||||
eval_mode,
|
eval_mode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn onJSCInvalidEnvVar(name: [*]const u8, len: usize) callconv(.C) void {
|
|
||||||
Output.prettyErrorln(
|
|
||||||
\\<r><red>error<r><d>:<r> invalid JSC environment variable
|
|
||||||
\\
|
|
||||||
\\ <b>{s}<r>
|
|
||||||
\\
|
|
||||||
\\For a list of options, see this file:
|
|
||||||
\\
|
|
||||||
\\ https://github.com/oven-sh/webkit/blob/main/Source/JavaScriptCore/runtime/OptionsList.h
|
|
||||||
\\
|
|
||||||
\\Environment variables must be prefixed with "BUN_JSC_". This code runs before .env files are loaded, so those won't work here.
|
|
||||||
\\
|
|
||||||
\\Warning: options change between releases of Bun and WebKit without notice. This is not a stable API, you should not rely on it beyond debugging something, and it may be removed entirely in a future version of Bun.
|
|
||||||
,
|
|
||||||
.{name[0..len]},
|
|
||||||
);
|
|
||||||
bun.Global.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns null on error. Use windows API to lookup the actual error.
|
/// Returns null on error. Use windows API to lookup the actual error.
|
||||||
/// The reason this function is in zig is so that we can use our own utf16-conversion functions.
|
/// The reason this function is in zig is so that we can use our own utf16-conversion functions.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ typedef struct ResolvedSource {
|
|||||||
BunString source_code;
|
BunString source_code;
|
||||||
BunString source_url;
|
BunString source_url;
|
||||||
bool isCommonJSModule;
|
bool isCommonJSModule;
|
||||||
uint32_t cjsCustomExtensionIndex;
|
uint32_t hash;
|
||||||
void* allocator;
|
void* allocator;
|
||||||
JSC::EncodedJSValue jsvalue_for_export;
|
JSC::EncodedJSValue jsvalue_for_export;
|
||||||
uint32_t tag;
|
uint32_t tag;
|
||||||
@@ -347,9 +347,7 @@ extern "C" JSC::JSInternalPromise* Bun__transpileFile(
|
|||||||
BunString* specifier,
|
BunString* specifier,
|
||||||
BunString* referrer,
|
BunString* referrer,
|
||||||
const BunString* typeAttribute,
|
const BunString* typeAttribute,
|
||||||
ErrorableResolvedSource* result,
|
ErrorableResolvedSource* result, bool allowPromise);
|
||||||
bool allowPromise,
|
|
||||||
bool isCommonJSRequire);
|
|
||||||
|
|
||||||
extern "C" bool Bun__fetchBuiltinModule(
|
extern "C" bool Bun__fetchBuiltinModule(
|
||||||
void* bunVM,
|
void* bunVM,
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public:
|
|||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBundlerPlugin;
|
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForBundlerPlugin;
|
||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeVMScript;
|
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForNodeVMScript;
|
||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSCommonJSModule;
|
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSCommonJSModule;
|
||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSCommonJSExtensions;
|
|
||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSMockImplementation;
|
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSMockImplementation;
|
||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSModuleMock;
|
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSModuleMock;
|
||||||
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSMockFunction;
|
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForJSMockFunction;
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public:
|
|||||||
std::unique_ptr<IsoSubspace> m_subspaceForBundlerPlugin;
|
std::unique_ptr<IsoSubspace> m_subspaceForBundlerPlugin;
|
||||||
std::unique_ptr<IsoSubspace> m_subspaceForNodeVMScript;
|
std::unique_ptr<IsoSubspace> m_subspaceForNodeVMScript;
|
||||||
std::unique_ptr<IsoSubspace> m_subspaceForJSCommonJSModule;
|
std::unique_ptr<IsoSubspace> m_subspaceForJSCommonJSModule;
|
||||||
std::unique_ptr<IsoSubspace> m_subspaceForJSCommonJSExtensions;
|
|
||||||
std::unique_ptr<IsoSubspace> m_subspaceForJSMockImplementation;
|
std::unique_ptr<IsoSubspace> m_subspaceForJSMockImplementation;
|
||||||
std::unique_ptr<IsoSubspace> m_subspaceForJSModuleMock;
|
std::unique_ptr<IsoSubspace> m_subspaceForJSModuleMock;
|
||||||
std::unique_ptr<IsoSubspace> m_subspaceForJSMockFunction;
|
std::unique_ptr<IsoSubspace> m_subspaceForJSMockFunction;
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ const PackageManager = @import("../install/install.zig").PackageManager;
|
|||||||
const IPC = @import("ipc.zig");
|
const IPC = @import("ipc.zig");
|
||||||
const DNSResolver = @import("api/bun/dns_resolver.zig").DNSResolver;
|
const DNSResolver = @import("api/bun/dns_resolver.zig").DNSResolver;
|
||||||
const Watcher = bun.Watcher;
|
const Watcher = bun.Watcher;
|
||||||
const node_module_module = @import("./bindings/NodeModuleModule.zig");
|
|
||||||
|
|
||||||
const ModuleLoader = JSC.ModuleLoader;
|
const ModuleLoader = JSC.ModuleLoader;
|
||||||
const FetchFlags = JSC.FetchFlags;
|
const FetchFlags = JSC.FetchFlags;
|
||||||
@@ -901,7 +900,7 @@ pub const VirtualMachine = struct {
|
|||||||
|
|
||||||
is_inside_deferred_task_queue: bool = false,
|
is_inside_deferred_task_queue: bool = false,
|
||||||
|
|
||||||
// defaults off. .on("message") will set it to true unless overridden
|
// defaults off. .on("message") will set it to true unles overridden
|
||||||
// process.channel.unref() will set it to false and mark it overridden
|
// process.channel.unref() will set it to false and mark it overridden
|
||||||
// on disconnect it will be disabled
|
// on disconnect it will be disabled
|
||||||
channel_ref: bun.Async.KeepAlive = .{},
|
channel_ref: bun.Async.KeepAlive = .{},
|
||||||
@@ -910,18 +909,6 @@ pub const VirtualMachine = struct {
|
|||||||
// if one disconnect event listener should be ignored
|
// if one disconnect event listener should be ignored
|
||||||
channel_ref_should_ignore_one_disconnect_event_listener: bool = false,
|
channel_ref_should_ignore_one_disconnect_event_listener: bool = false,
|
||||||
|
|
||||||
/// A set of extensions that exist in the require.extensions map. Keys
|
|
||||||
/// contain the leading '.'. Value is either a loader for built in
|
|
||||||
/// functions, or an index into JSCommonJSExtensions.
|
|
||||||
///
|
|
||||||
/// `.keys() == transpiler.resolver.opts.extra_cjs_extensions`, so
|
|
||||||
/// mutations in this map must update the resolver.
|
|
||||||
commonjs_custom_extensions: bun.StringArrayHashMapUnmanaged(node_module_module.CustomLoader.Packed) = .empty,
|
|
||||||
/// Incremented when the `require.extensions` for a built-in extension is mutated.
|
|
||||||
/// An example is mutating `require.extensions['.js']` to intercept all '.js' files.
|
|
||||||
/// The value is decremented when defaults are restored.
|
|
||||||
has_mutated_built_in_extensions: u32 = 0,
|
|
||||||
|
|
||||||
pub const OnUnhandledRejection = fn (*VirtualMachine, globalObject: *JSGlobalObject, JSValue) void;
|
pub const OnUnhandledRejection = fn (*VirtualMachine, globalObject: *JSGlobalObject, JSValue) void;
|
||||||
|
|
||||||
pub const OnException = fn (*ZigException) void;
|
pub const OnException = fn (*ZigException) void;
|
||||||
@@ -2380,6 +2367,7 @@ pub const VirtualMachine = struct {
|
|||||||
.source_code = bun.String.init(""),
|
.source_code = bun.String.init(""),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier.createIfDifferent(source_url),
|
.source_url = specifier.createIfDifferent(source_url),
|
||||||
|
.hash = 0,
|
||||||
.allocator = null,
|
.allocator = null,
|
||||||
.source_code_needs_deref = false,
|
.source_code_needs_deref = false,
|
||||||
};
|
};
|
||||||
@@ -2394,6 +2382,7 @@ pub const VirtualMachine = struct {
|
|||||||
.source_code = bun.String.init(source.impl),
|
.source_code = bun.String.init(source.impl),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier.createIfDifferent(source_url),
|
.source_url = specifier.createIfDifferent(source_url),
|
||||||
|
.hash = source.hash,
|
||||||
.allocator = source,
|
.allocator = source,
|
||||||
.source_code_needs_deref = false,
|
.source_code_needs_deref = false,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ const JSC = bun.JSC;
|
|||||||
const MarkedArrayBuffer = @import("./base.zig").MarkedArrayBuffer;
|
const MarkedArrayBuffer = @import("./base.zig").MarkedArrayBuffer;
|
||||||
const getAllocator = @import("./base.zig").getAllocator;
|
const getAllocator = @import("./base.zig").getAllocator;
|
||||||
const JSValue = bun.JSC.JSValue;
|
const JSValue = bun.JSC.JSValue;
|
||||||
const node_module_module = @import("./bindings/NodeModuleModule.zig");
|
|
||||||
|
|
||||||
const JSGlobalObject = bun.JSC.JSGlobalObject;
|
const JSGlobalObject = bun.JSC.JSGlobalObject;
|
||||||
const ExceptionValueRef = bun.JSC.ExceptionValueRef;
|
const ExceptionValueRef = bun.JSC.ExceptionValueRef;
|
||||||
@@ -79,6 +78,7 @@ inline fn jsSyntheticModule(name: ResolvedSource.Tag, specifier: String) Resolve
|
|||||||
.source_code = bun.String.empty,
|
.source_code = bun.String.empty,
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = bun.String.static(@tagName(name)),
|
.source_url = bun.String.static(@tagName(name)),
|
||||||
|
.hash = 0,
|
||||||
.tag = name,
|
.tag = name,
|
||||||
.source_code_needs_deref = false,
|
.source_code_needs_deref = false,
|
||||||
};
|
};
|
||||||
@@ -568,6 +568,7 @@ pub const RuntimeTranspilerStore = struct {
|
|||||||
break :brk result;
|
break :brk result;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.hash = 0,
|
||||||
.is_commonjs_module = entry.metadata.module_type == .cjs,
|
.is_commonjs_module = entry.metadata.module_type == .cjs,
|
||||||
.tag = this.resolved_source.tag,
|
.tag = this.resolved_source.tag,
|
||||||
};
|
};
|
||||||
@@ -581,6 +582,7 @@ pub const RuntimeTranspilerStore = struct {
|
|||||||
.allocator = null,
|
.allocator = null,
|
||||||
.source_code = bun.String.createLatin1(parse_result.source.contents),
|
.source_code = bun.String.createLatin1(parse_result.source.contents),
|
||||||
.already_bundled = true,
|
.already_bundled = true,
|
||||||
|
.hash = 0,
|
||||||
.bytecode_cache = if (bytecode_slice.len > 0) bytecode_slice.ptr else null,
|
.bytecode_cache = if (bytecode_slice.len > 0) bytecode_slice.ptr else null,
|
||||||
.bytecode_cache_size = bytecode_slice.len,
|
.bytecode_cache_size = bytecode_slice.len,
|
||||||
.is_commonjs_module = parse_result.already_bundled.isCommonJS(),
|
.is_commonjs_module = parse_result.already_bundled.isCommonJS(),
|
||||||
@@ -682,6 +684,7 @@ pub const RuntimeTranspilerStore = struct {
|
|||||||
.allocator = null,
|
.allocator = null,
|
||||||
.source_code = source_code,
|
.source_code = source_code,
|
||||||
.is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs,
|
.is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs,
|
||||||
|
.hash = 0,
|
||||||
.tag = this.resolved_source.tag,
|
.tag = this.resolved_source.tag,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1444,6 +1447,8 @@ pub const ModuleLoader = struct {
|
|||||||
.specifier = String.init(specifier),
|
.specifier = String.init(specifier),
|
||||||
.source_url = String.init(path.text),
|
.source_url = String.init(path.text),
|
||||||
.is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs,
|
.is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs,
|
||||||
|
|
||||||
|
.hash = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1504,6 +1509,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.empty,
|
.source_code = bun.String.empty,
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1735,6 +1741,8 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.createUTF8(parse_result.source.contents),
|
.source_code = bun.String.createUTF8(parse_result.source.contents),
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
|
||||||
|
.hash = 0,
|
||||||
.tag = ResolvedSource.Tag.json_for_object_loader,
|
.tag = ResolvedSource.Tag.json_for_object_loader,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1749,6 +1757,7 @@ pub const ModuleLoader = struct {
|
|||||||
},
|
},
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1758,6 +1767,7 @@ pub const ModuleLoader = struct {
|
|||||||
.allocator = null,
|
.allocator = null,
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.jsvalue_for_export = JSValue.createEmptyObject(jsc_vm.global, 0),
|
.jsvalue_for_export = JSValue.createEmptyObject(jsc_vm.global, 0),
|
||||||
.tag = .exports_object,
|
.tag = .exports_object,
|
||||||
};
|
};
|
||||||
@@ -1767,6 +1777,7 @@ pub const ModuleLoader = struct {
|
|||||||
.allocator = null,
|
.allocator = null,
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.jsvalue_for_export = parse_result.ast.parts.@"[0]"().stmts[0].data.s_expr.value.toJS(allocator, globalObject orelse jsc_vm.global) catch |e| panic("Unexpected JS error: {s}", .{@errorName(e)}),
|
.jsvalue_for_export = parse_result.ast.parts.@"[0]"().stmts[0].data.s_expr.value.toJS(allocator, globalObject orelse jsc_vm.global) catch |e| panic("Unexpected JS error: {s}", .{@errorName(e)}),
|
||||||
.tag = .exports_object,
|
.tag = .exports_object,
|
||||||
};
|
};
|
||||||
@@ -1780,6 +1791,7 @@ pub const ModuleLoader = struct {
|
|||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
.already_bundled = true,
|
.already_bundled = true,
|
||||||
|
.hash = 0,
|
||||||
.bytecode_cache = if (bytecode_slice.len > 0) bytecode_slice.ptr else null,
|
.bytecode_cache = if (bytecode_slice.len > 0) bytecode_slice.ptr else null,
|
||||||
.bytecode_cache_size = bytecode_slice.len,
|
.bytecode_cache_size = bytecode_slice.len,
|
||||||
.is_commonjs_module = parse_result.already_bundled.isCommonJS(),
|
.is_commonjs_module = parse_result.already_bundled.isCommonJS(),
|
||||||
@@ -1798,6 +1810,7 @@ pub const ModuleLoader = struct {
|
|||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
.is_commonjs_module = true,
|
.is_commonjs_module = true,
|
||||||
|
.hash = 0,
|
||||||
.tag = .javascript,
|
.tag = .javascript,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1826,6 +1839,7 @@ pub const ModuleLoader = struct {
|
|||||||
},
|
},
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.is_commonjs_module = entry.metadata.module_type == .cjs,
|
.is_commonjs_module = entry.metadata.module_type == .cjs,
|
||||||
.tag = brk: {
|
.tag = brk: {
|
||||||
if (entry.metadata.module_type == .cjs and parse_result.source.path.isFile()) {
|
if (entry.metadata.module_type == .cjs and parse_result.source.path.isFile()) {
|
||||||
@@ -1956,6 +1970,7 @@ pub const ModuleLoader = struct {
|
|||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
.is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs,
|
.is_commonjs_module = parse_result.ast.has_commonjs_export_names or parse_result.ast.exports_kind == .cjs,
|
||||||
|
.hash = 0,
|
||||||
.tag = tag,
|
.tag = tag,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -1998,6 +2013,7 @@ pub const ModuleLoader = struct {
|
|||||||
// .source_code = ZigString.init(jsc_vm.allocator.dupe(u8, parse_result.source.contents) catch unreachable),
|
// .source_code = ZigString.init(jsc_vm.allocator.dupe(u8, parse_result.source.contents) catch unreachable),
|
||||||
// .specifier = ZigString.init(specifier),
|
// .specifier = ZigString.init(specifier),
|
||||||
// .source_url = input_specifier.createIfDifferent(path.text),
|
// .source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
// .hash = 0,
|
||||||
// .tag = ResolvedSource.Tag.wasm,
|
// .tag = ResolvedSource.Tag.wasm,
|
||||||
// };
|
// };
|
||||||
// },
|
// },
|
||||||
@@ -2023,6 +2039,7 @@ pub const ModuleLoader = struct {
|
|||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
.tag = .esm,
|
.tag = .esm,
|
||||||
|
.hash = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2082,6 +2099,7 @@ pub const ModuleLoader = struct {
|
|||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
.tag = .esm,
|
.tag = .esm,
|
||||||
|
.hash = 0,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -2092,6 +2110,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.empty,
|
.source_code = bun.String.empty,
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.tag = .esm,
|
.tag = .esm,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2106,6 +2125,7 @@ pub const ModuleLoader = struct {
|
|||||||
.jsvalue_for_export = html_bundle.toJS(globalObject.?),
|
.jsvalue_for_export = html_bundle.toJS(globalObject.?),
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.tag = .export_default_object,
|
.tag = .export_default_object,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -2117,6 +2137,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.empty,
|
.source_code = bun.String.empty,
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.tag = .esm,
|
.tag = .esm,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2188,6 +2209,7 @@ pub const ModuleLoader = struct {
|
|||||||
.jsvalue_for_export = value,
|
.jsvalue_for_export = value,
|
||||||
.specifier = input_specifier,
|
.specifier = input_specifier,
|
||||||
.source_url = input_specifier.createIfDifferent(path.text),
|
.source_url = input_specifier.createIfDifferent(path.text),
|
||||||
|
.hash = 0,
|
||||||
.tag = .export_default_object,
|
.tag = .export_default_object,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -2255,7 +2277,6 @@ pub const ModuleLoader = struct {
|
|||||||
type_attribute: ?*const bun.String,
|
type_attribute: ?*const bun.String,
|
||||||
ret: *JSC.ErrorableResolvedSource,
|
ret: *JSC.ErrorableResolvedSource,
|
||||||
allow_promise: bool,
|
allow_promise: bool,
|
||||||
is_commonjs_require: bool,
|
|
||||||
) ?*anyopaque {
|
) ?*anyopaque {
|
||||||
JSC.markBinding(@src());
|
JSC.markBinding(@src());
|
||||||
var log = logger.Log.init(jsc_vm.transpiler.allocator);
|
var log = logger.Log.init(jsc_vm.transpiler.allocator);
|
||||||
@@ -2273,63 +2294,13 @@ pub const ModuleLoader = struct {
|
|||||||
|
|
||||||
var virtual_source_to_use: ?logger.Source = null;
|
var virtual_source_to_use: ?logger.Source = null;
|
||||||
var blob_to_deinit: ?JSC.WebCore.Blob = null;
|
var blob_to_deinit: ?JSC.WebCore.Blob = null;
|
||||||
var lr = options.getLoaderAndVirtualSource(_specifier.slice(), jsc_vm, &virtual_source_to_use, &blob_to_deinit, type_attribute_str) catch {
|
const lr = options.getLoaderAndVirtualSource(_specifier.slice(), jsc_vm, &virtual_source_to_use, &blob_to_deinit, type_attribute_str) catch {
|
||||||
ret.* = JSC.ErrorableResolvedSource.err(error.JSErrorObject, globalObject.MODULE_NOT_FOUND("Blob not found", .{}).toJS().asVoid());
|
ret.* = JSC.ErrorableResolvedSource.err(error.JSErrorObject, globalObject.MODULE_NOT_FOUND("Blob not found", .{}).toJS().asVoid());
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
defer if (blob_to_deinit) |*blob| blob.deinit();
|
defer if (blob_to_deinit) |*blob| blob.deinit();
|
||||||
|
|
||||||
if (is_commonjs_require and jsc_vm.has_mutated_built_in_extensions > 0) brk: {
|
const module_type: options.ModuleType = if (lr.package_json) |pkg| pkg.module_type else .unknown;
|
||||||
@branchHint(.unlikely);
|
|
||||||
if (node_module_module.findLongestRegisteredExtension(jsc_vm, _specifier.slice())) |entry| {
|
|
||||||
switch (entry) {
|
|
||||||
.loader => |loader| {
|
|
||||||
lr.loader = loader;
|
|
||||||
break :brk;
|
|
||||||
},
|
|
||||||
.custom => |index| {
|
|
||||||
ret.* = JSC.ErrorableResolvedSource.ok(ResolvedSource{
|
|
||||||
.allocator = null,
|
|
||||||
.source_code = bun.String.empty,
|
|
||||||
.specifier = .empty,
|
|
||||||
.source_url = .empty,
|
|
||||||
.cjs_custom_extension_index = index,
|
|
||||||
.tag = .common_js_custom_extension,
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const module_type: options.ModuleType = brk: {
|
|
||||||
const ext = lr.path.name.ext;
|
|
||||||
// regular expression /.[cm][jt]s$/
|
|
||||||
if (ext.len == ".cjs".len) {
|
|
||||||
if (strings.eqlComptimeIgnoreLen(ext, ".cjs"))
|
|
||||||
break :brk .cjs;
|
|
||||||
if (strings.eqlComptimeIgnoreLen(ext, ".mjs"))
|
|
||||||
break :brk .esm;
|
|
||||||
if (strings.eqlComptimeIgnoreLen(ext, ".cts"))
|
|
||||||
break :brk .cjs;
|
|
||||||
if (strings.eqlComptimeIgnoreLen(ext, ".mts"))
|
|
||||||
break :brk .esm;
|
|
||||||
}
|
|
||||||
// regular expression /.[jt]s$/
|
|
||||||
if (ext.len == ".ts".len) {
|
|
||||||
if (strings.eqlComptimeIgnoreLen(ext, ".js") or
|
|
||||||
strings.eqlComptimeIgnoreLen(ext, ".ts"))
|
|
||||||
{
|
|
||||||
// Use the package.json module type if it exists
|
|
||||||
break :brk if (lr.package_json) |pkg|
|
|
||||||
pkg.module_type
|
|
||||||
else
|
|
||||||
.unknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// For JSX TSX and other extensions, let the file contents.
|
|
||||||
break :brk .unknown;
|
|
||||||
};
|
|
||||||
const pkg_name: ?[]const u8 = if (lr.package_json) |pkg|
|
const pkg_name: ?[]const u8 = if (lr.package_json) |pkg|
|
||||||
if (pkg.name.len > 0) pkg.name else null
|
if (pkg.name.len > 0) pkg.name else null
|
||||||
else
|
else
|
||||||
@@ -2396,48 +2367,19 @@ pub const ModuleLoader = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const synchronous_loader: options.Loader = lr.loader orelse loader: {
|
const synchronous_loader = lr.loader orelse loader: {
|
||||||
if (jsc_vm.has_loaded or jsc_vm.is_in_preload) {
|
if (jsc_vm.has_loaded or jsc_vm.is_in_preload) {
|
||||||
// Extensionless files in this context are treated as the JS loader
|
// Extensionless files in this context are treated as the JS loader
|
||||||
if (lr.path.name.ext.len == 0) {
|
if (lr.path.name.ext.len == 0) {
|
||||||
break :loader .tsx;
|
break :loader options.Loader.tsx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown extensions are to be treated as file loader
|
// Unknown extensions are to be treated as file loader
|
||||||
if (is_commonjs_require) {
|
break :loader options.Loader.file;
|
||||||
if (jsc_vm.commonjs_custom_extensions.entries.len > 0 and
|
|
||||||
jsc_vm.has_mutated_built_in_extensions == 0)
|
|
||||||
{
|
|
||||||
@branchHint(.unlikely);
|
|
||||||
if (node_module_module.findLongestRegisteredExtension(jsc_vm, lr.path.text)) |entry| {
|
|
||||||
switch (entry) {
|
|
||||||
.loader => |loader| break :loader loader,
|
|
||||||
.custom => |index| {
|
|
||||||
ret.* = JSC.ErrorableResolvedSource.ok(ResolvedSource{
|
|
||||||
.allocator = null,
|
|
||||||
.source_code = bun.String.empty,
|
|
||||||
.specifier = .empty,
|
|
||||||
.source_url = .empty,
|
|
||||||
.cjs_custom_extension_index = index,
|
|
||||||
.tag = .common_js_custom_extension,
|
|
||||||
});
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For Node.js compatibility, requiring a file with an
|
|
||||||
// unknown extension will be treated as a JS file
|
|
||||||
break :loader .ts;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For ESM, Bun treats unknown extensions as file loader
|
|
||||||
break :loader .file;
|
|
||||||
} else {
|
} else {
|
||||||
// Unless it's potentially the main module
|
// Unless it's potentially the main module
|
||||||
// This is important so that "bun run ./foo-i-have-no-extension" works
|
// This is important so that "bun run ./foo-i-have-no-extension" works
|
||||||
break :loader .tsx;
|
break :loader options.Loader.tsx;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2509,6 +2451,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.createUTF8(jsc_vm.entry_point.source.contents),
|
.source_code = bun.String.createUTF8(jsc_vm.entry_point.source.contents),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier,
|
.source_url = specifier,
|
||||||
|
.hash = 0,
|
||||||
.tag = .esm,
|
.tag = .esm,
|
||||||
.source_code_needs_deref = true,
|
.source_code_needs_deref = true,
|
||||||
},
|
},
|
||||||
@@ -2524,6 +2467,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = String.init(Runtime.Runtime.sourceCode()),
|
.source_code = String.init(Runtime.Runtime.sourceCode()),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier,
|
.source_url = specifier,
|
||||||
|
.hash = Runtime.Runtime.versionHash(),
|
||||||
},
|
},
|
||||||
inline else => |tag| jsSyntheticModule(@field(ResolvedSource.Tag, @tagName(tag)), specifier),
|
inline else => |tag| jsSyntheticModule(@field(ResolvedSource.Tag, @tagName(tag)), specifier),
|
||||||
};
|
};
|
||||||
@@ -2543,6 +2487,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.createUTF8(entry.source.contents),
|
.source_code = bun.String.createUTF8(entry.source.contents),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier.dupeRef(),
|
.source_url = specifier.dupeRef(),
|
||||||
|
.hash = 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else if (jsc_vm.standalone_module_graph) |graph| {
|
} else if (jsc_vm.standalone_module_graph) |graph| {
|
||||||
@@ -2564,6 +2509,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = bun.String.static(code),
|
.source_code = bun.String.static(code),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier.dupeRef(),
|
.source_url = specifier.dupeRef(),
|
||||||
|
.hash = 0,
|
||||||
.source_code_needs_deref = false,
|
.source_code_needs_deref = false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -2573,6 +2519,7 @@ pub const ModuleLoader = struct {
|
|||||||
.source_code = file.toWTFString(),
|
.source_code = file.toWTFString(),
|
||||||
.specifier = specifier,
|
.specifier = specifier,
|
||||||
.source_url = specifier.dupeRef(),
|
.source_url = specifier.dupeRef(),
|
||||||
|
.hash = 0,
|
||||||
.source_code_needs_deref = false,
|
.source_code_needs_deref = false,
|
||||||
.bytecode_cache = if (file.bytecode.len > 0) file.bytecode.ptr else null,
|
.bytecode_cache = if (file.bytecode.len > 0) file.bytecode.ptr else null,
|
||||||
.bytecode_cache_size = file.bytecode.len,
|
.bytecode_cache_size = file.bytecode.len,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
#include <JavaScriptCore/JSInternalPromise.h>
|
#include <JavaScriptCore/JSInternalPromise.h>
|
||||||
#include "JavaScriptCore/Completion.h"
|
#include "JavaScriptCore/Completion.h"
|
||||||
#include "JavaScriptCore/JSNativeStdFunction.h"
|
#include "JavaScriptCore/JSNativeStdFunction.h"
|
||||||
#include "JSCommonJSExtensions.h"
|
|
||||||
|
|
||||||
#include "PathInlines.h"
|
#include "PathInlines.h"
|
||||||
#include "ZigGlobalObject.h"
|
#include "ZigGlobalObject.h"
|
||||||
@@ -563,12 +562,6 @@ static JSValue getModuleCacheObject(VM& vm, JSObject* moduleObject)
|
|||||||
->lazyRequireCacheObject();
|
->lazyRequireCacheObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue getModuleExtensionsObject(VM& vm, JSObject* moduleObject)
|
|
||||||
{
|
|
||||||
return jsCast<Zig::GlobalObject*>(moduleObject->globalObject())
|
|
||||||
->lazyRequireExtensionsObject();
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue getModuleDebugObject(VM& vm, JSObject* moduleObject)
|
static JSValue getModuleDebugObject(VM& vm, JSObject* moduleObject)
|
||||||
{
|
{
|
||||||
return JSC::constructEmptyObject(moduleObject->globalObject());
|
return JSC::constructEmptyObject(moduleObject->globalObject());
|
||||||
@@ -581,6 +574,13 @@ static JSValue getPathCacheObject(VM& vm, JSObject* moduleObject)
|
|||||||
vm, globalObject->nullPrototypeObjectStructure());
|
vm, globalObject->nullPrototypeObjectStructure());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSValue getModuleExtensionsObject(VM& vm, JSObject* moduleObject)
|
||||||
|
{
|
||||||
|
auto* globalObject = defaultGlobalObject(moduleObject->globalObject());
|
||||||
|
return globalObject->requireFunctionUnbound()->getIfPropertyExists(
|
||||||
|
globalObject, Identifier::fromString(vm, "extensions"_s));
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue getSourceMapFunction(VM& vm, JSObject* moduleObject)
|
static JSValue getSourceMapFunction(VM& vm, JSObject* moduleObject)
|
||||||
{
|
{
|
||||||
auto* globalObject = defaultGlobalObject(moduleObject->globalObject());
|
auto* globalObject = defaultGlobalObject(moduleObject->globalObject());
|
||||||
@@ -951,27 +951,6 @@ void addNodeModuleConstructorProperties(JSC::VM& vm,
|
|||||||
JSC::NoIntrinsic, jsFunctionResolveFileName);
|
JSC::NoIntrinsic, jsFunctionResolveFileName);
|
||||||
init.set(resolveFilenameFunction);
|
init.set(resolveFilenameFunction);
|
||||||
});
|
});
|
||||||
|
|
||||||
globalObject->m_lazyRequireCacheObject.initLater(
|
|
||||||
[](const Zig::GlobalObject::Initializer<JSObject>& init) {
|
|
||||||
JSC::VM& vm = init.vm;
|
|
||||||
JSC::JSGlobalObject* globalObject = init.owner;
|
|
||||||
|
|
||||||
auto* function = JSFunction::create(vm, globalObject, static_cast<JSC::FunctionExecutable*>(commonJSCreateRequireCacheCodeGenerator(vm)), globalObject);
|
|
||||||
|
|
||||||
NakedPtr<JSC::Exception> returnedException = nullptr;
|
|
||||||
auto result = JSC::profiledCall(globalObject, ProfilingReason::API, function, JSC::getCallData(function), globalObject, ArgList(), returnedException);
|
|
||||||
ASSERT(!returnedException);
|
|
||||||
init.set(result.toObject(globalObject));
|
|
||||||
});
|
|
||||||
|
|
||||||
globalObject->m_lazyRequireExtensionsObject.initLater(
|
|
||||||
[](const Zig::GlobalObject::Initializer<Bun::JSCommonJSExtensions>& init) {
|
|
||||||
JSC::VM& vm = init.vm;
|
|
||||||
JSC::JSGlobalObject* globalObject = init.owner;
|
|
||||||
|
|
||||||
init.set(JSCommonJSExtensions::create(vm, globalObject, JSCommonJSExtensions::createStructure(vm, globalObject, globalObject->nullPrototype())));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsModuleResolveFilenameSlowPathEnabled,
|
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsModuleResolveFilenameSlowPathEnabled,
|
||||||
|
|||||||
@@ -395,6 +395,7 @@ writeIfNotChanged(
|
|||||||
path.join(CODEGEN_DIR, "ResolvedSourceTag.zig"),
|
path.join(CODEGEN_DIR, "ResolvedSourceTag.zig"),
|
||||||
`// zig fmt: off
|
`// zig fmt: off
|
||||||
pub const ResolvedSourceTag = enum(u32) {
|
pub const ResolvedSourceTag = enum(u32) {
|
||||||
|
// Predefined
|
||||||
javascript = 0,
|
javascript = 0,
|
||||||
package_json_type_module = 1,
|
package_json_type_module = 1,
|
||||||
package_json_type_commonjs = 2,
|
package_json_type_commonjs = 2,
|
||||||
@@ -403,12 +404,11 @@ pub const ResolvedSourceTag = enum(u32) {
|
|||||||
file = 5,
|
file = 5,
|
||||||
esm = 6,
|
esm = 6,
|
||||||
json_for_object_loader = 7,
|
json_for_object_loader = 7,
|
||||||
/// Generate an object with "default" set to all the exports, including a "default" property
|
/// Generate an object with "default" set to all the exports, including a "default" propert
|
||||||
exports_object = 8,
|
exports_object = 8,
|
||||||
|
|
||||||
/// Generate a module that only exports default the input JSValue
|
/// Generate a module that only exports default the input JSValue
|
||||||
export_default_object = 9,
|
export_default_object = 9,
|
||||||
/// Signal upwards that the matching value in 'require.extensions' should be used.
|
|
||||||
common_js_custom_extension = 10,
|
|
||||||
|
|
||||||
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
|
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
|
||||||
// In this enum are represented as \`(1 << 9) & id\`
|
// In this enum are represented as \`(1 << 9) & id\`
|
||||||
@@ -438,7 +438,6 @@ writeIfNotChanged(
|
|||||||
JSONForObjectLoader = 7,
|
JSONForObjectLoader = 7,
|
||||||
ExportsObject = 8,
|
ExportsObject = 8,
|
||||||
ExportDefaultObject = 9,
|
ExportDefaultObject = 9,
|
||||||
CommonJSCustomExtension = 10,
|
|
||||||
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
|
// Built in modules are loaded through InternalModuleRegistry by numerical ID.
|
||||||
// In this enum are represented as \`(1 << 9) & id\`
|
// In this enum are represented as \`(1 << 9) & id\`
|
||||||
InternalModuleRegistryFlag = 1 << 9,
|
InternalModuleRegistryFlag = 1 << 9,
|
||||||
|
|||||||
2
src/js/builtins.d.ts
vendored
2
src/js/builtins.d.ts
vendored
@@ -484,7 +484,7 @@ declare function $createCommonJSModule(
|
|||||||
id: string,
|
id: string,
|
||||||
exports: any,
|
exports: any,
|
||||||
hasEvaluated: boolean,
|
hasEvaluated: boolean,
|
||||||
parent: JSCommonJSModule | undefined,
|
parent: ?JSCommonJSModule,
|
||||||
): JSCommonJSModule;
|
): JSCommonJSModule;
|
||||||
declare function $evaluateCommonJSModule(
|
declare function $evaluateCommonJSModule(
|
||||||
moduleToEvaluate: JSCommonJSModule,
|
moduleToEvaluate: JSCommonJSModule,
|
||||||
|
|||||||
@@ -3590,6 +3590,9 @@ pub const Parser = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const did_import_fast_refresh = false;
|
||||||
|
_ = did_import_fast_refresh;
|
||||||
|
|
||||||
// This is a workaround for broken module environment checks in packages like lodash-es
|
// This is a workaround for broken module environment checks in packages like lodash-es
|
||||||
// https://github.com/lodash/lodash/issues/5660
|
// https://github.com/lodash/lodash/issues/5660
|
||||||
var force_esm = false;
|
var force_esm = false;
|
||||||
@@ -3961,13 +3964,7 @@ pub const Parser = struct {
|
|||||||
switch (p.options.module_type) {
|
switch (p.options.module_type) {
|
||||||
// ".cjs" or ".cts" or ("type: commonjs" and (".js" or ".jsx" or ".ts" or ".tsx"))
|
// ".cjs" or ".cts" or ("type: commonjs" and (".js" or ".jsx" or ".ts" or ".tsx"))
|
||||||
.cjs => {
|
.cjs => {
|
||||||
// There are no commonjs-only features used (require is allowed in ESM)
|
exports_kind = .cjs;
|
||||||
bun.assert(!uses_exports_ref and
|
|
||||||
!uses_module_ref and
|
|
||||||
!p.has_top_level_return and
|
|
||||||
!p.has_with_scope);
|
|
||||||
// Use ESM if the file has ES module syntax (import)
|
|
||||||
exports_kind = if (p.has_es_module_syntax) .esm else .cjs;
|
|
||||||
},
|
},
|
||||||
.esm => {
|
.esm => {
|
||||||
exports_kind = .esm;
|
exports_kind = .esm;
|
||||||
|
|||||||
@@ -80,9 +80,9 @@ pub fn stringHashMapFromArrays(comptime t: type, allocator: std.mem.Allocator, k
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub const ExternalModules = struct {
|
pub const ExternalModules = struct {
|
||||||
node_modules: std.BufSet,
|
node_modules: std.BufSet = undefined,
|
||||||
abs_paths: std.BufSet,
|
abs_paths: std.BufSet = undefined,
|
||||||
patterns: []const WildcardPattern,
|
patterns: []const WildcardPattern = undefined,
|
||||||
|
|
||||||
pub const WildcardPattern = struct {
|
pub const WildcardPattern = struct {
|
||||||
prefix: string,
|
prefix: string,
|
||||||
@@ -1700,7 +1700,7 @@ pub const BundleOptions = struct {
|
|||||||
main_fields: []const string = Target.DefaultMainFields.get(Target.browser),
|
main_fields: []const string = Target.DefaultMainFields.get(Target.browser),
|
||||||
/// TODO: remove this in favor accessing bundler.log
|
/// TODO: remove this in favor accessing bundler.log
|
||||||
log: *logger.Log,
|
log: *logger.Log,
|
||||||
external: ExternalModules,
|
external: ExternalModules = ExternalModules{},
|
||||||
entry_points: []const string,
|
entry_points: []const string,
|
||||||
entry_naming: []const u8 = "",
|
entry_naming: []const u8 = "",
|
||||||
asset_naming: []const u8 = "",
|
asset_naming: []const u8 = "",
|
||||||
@@ -1708,9 +1708,6 @@ pub const BundleOptions = struct {
|
|||||||
public_path: []const u8 = "",
|
public_path: []const u8 = "",
|
||||||
extension_order: ResolveFileExtensions = .{},
|
extension_order: ResolveFileExtensions = .{},
|
||||||
main_field_extension_order: []const string = &Defaults.MainFieldExtensionOrder,
|
main_field_extension_order: []const string = &Defaults.MainFieldExtensionOrder,
|
||||||
/// This list applies to all extension resolution cases. The runtime uses
|
|
||||||
/// this for implementing `require.extensions`
|
|
||||||
extra_cjs_extensions: []const []const u8 = &.{},
|
|
||||||
out_extensions: bun.StringHashMap(string),
|
out_extensions: bun.StringHashMap(string),
|
||||||
import_path_format: ImportPathFormat = ImportPathFormat.relative,
|
import_path_format: ImportPathFormat = ImportPathFormat.relative,
|
||||||
defines_loaded: bool = false,
|
defines_loaded: bool = false,
|
||||||
|
|||||||
@@ -604,7 +604,7 @@ pub const PackageJSON = struct {
|
|||||||
null,
|
null,
|
||||||
) catch |err| {
|
) catch |err| {
|
||||||
if (err != error.IsDir) {
|
if (err != error.IsDir) {
|
||||||
r.log.addErrorFmt(null, logger.Loc.Empty, allocator, "Cannot read file \"{s}\": {s}", .{ input_path, @errorName(err) }) catch unreachable;
|
r.log.addErrorFmt(null, logger.Loc.Empty, allocator, "Cannot read file \"{s}\": {s}", .{ r.prettyPath(fs.Path.init(input_path)), @errorName(err) }) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -618,7 +618,7 @@ pub const PackageJSON = struct {
|
|||||||
const key_path = fs.Path.init(package_json_path);
|
const key_path = fs.Path.init(package_json_path);
|
||||||
|
|
||||||
var json_source = logger.Source.initPathString(key_path.text, entry.contents);
|
var json_source = logger.Source.initPathString(key_path.text, entry.contents);
|
||||||
json_source.path.pretty = json_source.path.text;
|
json_source.path.pretty = r.prettyPath(json_source.path);
|
||||||
|
|
||||||
const json: js_ast.Expr = (r.caches.json.parsePackageJSON(r.log, json_source, allocator, true) catch |err| {
|
const json: js_ast.Expr = (r.caches.json.parsePackageJSON(r.log, json_source, allocator, true) catch |err| {
|
||||||
if (Environment.isDebug) {
|
if (Environment.isDebug) {
|
||||||
|
|||||||
@@ -2565,6 +2565,11 @@ pub const Resolver = struct {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
pub fn prettyPath(_: *ThisResolver, path: Path) string {
|
||||||
|
return path.text;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn binDirs(_: *const ThisResolver) []const string {
|
pub fn binDirs(_: *const ThisResolver) []const string {
|
||||||
if (!bin_folders_loaded) return &[_]string{};
|
if (!bin_folders_loaded) return &[_]string{};
|
||||||
return bin_folders.constSlice();
|
return bin_folders.constSlice();
|
||||||
@@ -2828,7 +2833,7 @@ pub const Resolver = struct {
|
|||||||
r.dir_cache.markNotFound(queue_top.result);
|
r.dir_cache.markNotFound(queue_top.result);
|
||||||
rfs.entries.markNotFound(cached_dir_entry_result);
|
rfs.entries.markNotFound(cached_dir_entry_result);
|
||||||
if (comptime enable_logging) {
|
if (comptime enable_logging) {
|
||||||
const pretty = queue_top.unsafe_path;
|
const pretty = r.prettyPath(Path.init(queue_top.unsafe_path));
|
||||||
|
|
||||||
r.log.addErrorFmt(
|
r.log.addErrorFmt(
|
||||||
null,
|
null,
|
||||||
@@ -3466,68 +3471,54 @@ pub const Resolver = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn loadAsIndex(r: *ThisResolver, dir_info: *DirInfo, extension_order: []const string) ?MatchResult {
|
pub fn loadAsIndex(r: *ThisResolver, dir_info: *DirInfo, extension_order: []const string) ?MatchResult {
|
||||||
|
const rfs = &r.fs.fs;
|
||||||
// Try the "index" file with extensions
|
// Try the "index" file with extensions
|
||||||
for (extension_order) |ext| {
|
for (extension_order) |ext| {
|
||||||
if (loadIndexWithExtension(r, dir_info, ext)) |result| {
|
var ext_buf = bufs(.extension_path);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (r.opts.extra_cjs_extensions) |ext| {
|
|
||||||
if (loadIndexWithExtension(r, dir_info, ext)) |result| {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
var base = ext_buf[0 .. "index".len + ext.len];
|
||||||
}
|
base[0.."index".len].* = "index".*;
|
||||||
|
bun.copy(u8, base["index".len..], ext);
|
||||||
|
|
||||||
fn loadIndexWithExtension(r: *ThisResolver, dir_info: *DirInfo, ext: string) ?MatchResult {
|
if (dir_info.getEntries(r.generation)) |entries| {
|
||||||
const rfs = &r.fs.fs;
|
if (entries.get(base)) |lookup| {
|
||||||
|
if (lookup.entry.kind(rfs, r.store_fd) == .file) {
|
||||||
|
const out_buf = brk: {
|
||||||
|
if (lookup.entry.abs_path.isEmpty()) {
|
||||||
|
const parts = [_]string{ dir_info.abs_path, base };
|
||||||
|
const out_buf_ = r.fs.absBuf(&parts, bufs(.index));
|
||||||
|
lookup.entry.abs_path =
|
||||||
|
PathString.init(r.fs.dirname_store.append(@TypeOf(out_buf_), out_buf_) catch unreachable);
|
||||||
|
}
|
||||||
|
break :brk lookup.entry.abs_path.slice();
|
||||||
|
};
|
||||||
|
|
||||||
var ext_buf = bufs(.extension_path);
|
if (r.debug_logs) |*debug| {
|
||||||
|
debug.addNoteFmt("Found file: \"{s}\"", .{out_buf});
|
||||||
var base = ext_buf[0 .. "index".len + ext.len];
|
|
||||||
base[0.."index".len].* = "index".*;
|
|
||||||
bun.copy(u8, base["index".len..], ext);
|
|
||||||
|
|
||||||
if (dir_info.getEntries(r.generation)) |entries| {
|
|
||||||
if (entries.get(base)) |lookup| {
|
|
||||||
if (lookup.entry.kind(rfs, r.store_fd) == .file) {
|
|
||||||
const out_buf = brk: {
|
|
||||||
if (lookup.entry.abs_path.isEmpty()) {
|
|
||||||
const parts = [_]string{ dir_info.abs_path, base };
|
|
||||||
const out_buf_ = r.fs.absBuf(&parts, bufs(.index));
|
|
||||||
lookup.entry.abs_path =
|
|
||||||
PathString.init(r.fs.dirname_store.append(@TypeOf(out_buf_), out_buf_) catch unreachable);
|
|
||||||
}
|
}
|
||||||
break :brk lookup.entry.abs_path.slice();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (r.debug_logs) |*debug| {
|
if (dir_info.package_json) |package_json| {
|
||||||
debug.addNoteFmt("Found file: \"{s}\"", .{out_buf});
|
return MatchResult{
|
||||||
}
|
.path_pair = .{ .primary = Path.init(out_buf) },
|
||||||
|
.diff_case = lookup.diff_case,
|
||||||
|
.package_json = package_json,
|
||||||
|
.dirname_fd = dir_info.getFileDescriptor(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (dir_info.package_json) |package_json| {
|
|
||||||
return MatchResult{
|
return MatchResult{
|
||||||
.path_pair = .{ .primary = Path.init(out_buf) },
|
.path_pair = .{ .primary = Path.init(out_buf) },
|
||||||
.diff_case = lookup.diff_case,
|
.diff_case = lookup.diff_case,
|
||||||
.package_json = package_json,
|
|
||||||
.dirname_fd = dir_info.getFileDescriptor(),
|
.dirname_fd = dir_info.getFileDescriptor(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return MatchResult{
|
|
||||||
.path_pair = .{ .primary = Path.init(out_buf) },
|
|
||||||
.diff_case = lookup.diff_case,
|
|
||||||
|
|
||||||
.dirname_fd = dir_info.getFileDescriptor(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (r.debug_logs) |*debug| {
|
if (r.debug_logs) |*debug| {
|
||||||
debug.addNoteFmt("Failed to find file: \"{s}/{s}\"", .{ dir_info.abs_path, base });
|
debug.addNoteFmt("Failed to find file: \"{s}/{s}\"", .{ dir_info.abs_path, base });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -3751,7 +3742,7 @@ pub const Resolver = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn loadAsFile(r: *ThisResolver, path: string, extension_order: []const string) ?LoadResult {
|
pub fn loadAsFile(r: *ThisResolver, path: string, extension_order: []const string) ?LoadResult {
|
||||||
const rfs: *Fs.FileSystem.RealFS = &r.fs.fs;
|
var rfs: *Fs.FileSystem.RealFS = &r.fs.fs;
|
||||||
|
|
||||||
if (r.debug_logs) |*debug| {
|
if (r.debug_logs) |*debug| {
|
||||||
debug.addNoteFmt("Attempting to load \"{s}\" as a file", .{path});
|
debug.addNoteFmt("Attempting to load \"{s}\" as a file", .{path});
|
||||||
@@ -3783,7 +3774,7 @@ pub const Resolver = struct {
|
|||||||
r.allocator,
|
r.allocator,
|
||||||
"Cannot read directory \"{s}\": {s}",
|
"Cannot read directory \"{s}\": {s}",
|
||||||
.{
|
.{
|
||||||
dir_path,
|
r.prettyPath(Path.init(dir_path)),
|
||||||
@errorName(dir_entry.err.original_err),
|
@errorName(dir_entry.err.original_err),
|
||||||
},
|
},
|
||||||
) catch {};
|
) catch {};
|
||||||
@@ -3827,14 +3818,35 @@ pub const Resolver = struct {
|
|||||||
// Try the path with extensions
|
// Try the path with extensions
|
||||||
bun.copy(u8, bufs(.load_as_file), path);
|
bun.copy(u8, bufs(.load_as_file), path);
|
||||||
for (extension_order) |ext| {
|
for (extension_order) |ext| {
|
||||||
if (loadExtension(r, base, path, ext, entries)) |result| {
|
var buffer = bufs(.load_as_file)[0 .. path.len + ext.len];
|
||||||
return result;
|
bun.copy(u8, buffer[path.len..], ext);
|
||||||
}
|
const file_name = buffer[path.len - base.len .. buffer.len];
|
||||||
}
|
|
||||||
|
|
||||||
for (r.opts.extra_cjs_extensions) |ext| {
|
if (r.debug_logs) |*debug| {
|
||||||
if (loadExtension(r, base, path, ext, entries)) |result| {
|
debug.addNoteFmt("Checking for file \"{s}\" ", .{buffer});
|
||||||
return result;
|
}
|
||||||
|
|
||||||
|
if (entries.get(file_name)) |query| {
|
||||||
|
if (query.entry.kind(rfs, r.store_fd) == .file) {
|
||||||
|
if (r.debug_logs) |*debug| {
|
||||||
|
debug.addNoteFmt("Found file \"{s}\" ", .{buffer});
|
||||||
|
}
|
||||||
|
|
||||||
|
// now that we've found it, we allocate it.
|
||||||
|
return LoadResult{
|
||||||
|
.path = brk: {
|
||||||
|
query.entry.abs_path = if (query.entry.abs_path.isEmpty())
|
||||||
|
PathString.init(r.fs.dirname_store.append(@TypeOf(buffer), buffer) catch unreachable)
|
||||||
|
else
|
||||||
|
query.entry.abs_path;
|
||||||
|
|
||||||
|
break :brk query.entry.abs_path.slice();
|
||||||
|
},
|
||||||
|
.diff_case = query.diff_case,
|
||||||
|
.dirname_fd = entries.fd,
|
||||||
|
.file_fd = query.entry.cache.fd,
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3919,42 +3931,6 @@ pub const Resolver = struct {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn loadExtension(r: *ThisResolver, base: string, path: string, ext: string, entries: *Fs.FileSystem.DirEntry) ?LoadResult {
|
|
||||||
const rfs: *Fs.FileSystem.RealFS = &r.fs.fs;
|
|
||||||
const buffer = bufs(.load_as_file)[0 .. path.len + ext.len];
|
|
||||||
bun.copy(u8, buffer[path.len..], ext);
|
|
||||||
const file_name = buffer[path.len - base.len .. buffer.len];
|
|
||||||
|
|
||||||
if (r.debug_logs) |*debug| {
|
|
||||||
debug.addNoteFmt("Checking for file \"{s}\" ", .{buffer});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entries.get(file_name)) |query| {
|
|
||||||
if (query.entry.kind(rfs, r.store_fd) == .file) {
|
|
||||||
if (r.debug_logs) |*debug| {
|
|
||||||
debug.addNoteFmt("Found file \"{s}\" ", .{buffer});
|
|
||||||
}
|
|
||||||
|
|
||||||
// now that we've found it, we allocate it.
|
|
||||||
return .{
|
|
||||||
.path = brk: {
|
|
||||||
query.entry.abs_path = if (query.entry.abs_path.isEmpty())
|
|
||||||
PathString.init(r.fs.dirname_store.append(@TypeOf(buffer), buffer) catch unreachable)
|
|
||||||
else
|
|
||||||
query.entry.abs_path;
|
|
||||||
|
|
||||||
break :brk query.entry.abs_path.slice();
|
|
||||||
},
|
|
||||||
.diff_case = query.diff_case,
|
|
||||||
.dirname_fd = entries.fd,
|
|
||||||
.file_fd = query.entry.cache.fd,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dirInfoUncached(
|
fn dirInfoUncached(
|
||||||
r: *ThisResolver,
|
r: *ThisResolver,
|
||||||
info: *DirInfo,
|
info: *DirInfo,
|
||||||
@@ -4162,7 +4138,8 @@ pub const Resolver = struct {
|
|||||||
tsconfigpath,
|
tsconfigpath,
|
||||||
if (FeatureFlags.store_file_descriptors) fd else .zero,
|
if (FeatureFlags.store_file_descriptors) fd else .zero,
|
||||||
) catch |err| brk: {
|
) catch |err| brk: {
|
||||||
const pretty = tsconfigpath;
|
const pretty = r.prettyPath(Path.init(tsconfigpath));
|
||||||
|
|
||||||
if (err == error.ENOENT or err == error.FileNotFound) {
|
if (err == error.ENOENT or err == error.FileNotFound) {
|
||||||
r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot find tsconfig file {}", .{bun.fmt.QuotedFormatter{ .text = pretty }}) catch {};
|
r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot find tsconfig file {}", .{bun.fmt.QuotedFormatter{ .text = pretty }}) catch {};
|
||||||
} else if (err != error.ParseErrorAlreadyLogged and err != error.IsDir and err != error.EISDIR) {
|
} else if (err != error.ParseErrorAlreadyLogged and err != error.IsDir and err != error.EISDIR) {
|
||||||
|
|||||||
@@ -1177,21 +1177,21 @@ pub const Transpiler = struct {
|
|||||||
transpiler.log,
|
transpiler.log,
|
||||||
&source,
|
&source,
|
||||||
) catch null) orelse return null) {
|
) catch null) orelse return null) {
|
||||||
.ast => |value| .{
|
.ast => |value| ParseResult{
|
||||||
.ast = value,
|
.ast = value,
|
||||||
.source = source,
|
.source = source,
|
||||||
.loader = loader,
|
.loader = loader,
|
||||||
.input_fd = input_fd,
|
.input_fd = input_fd,
|
||||||
.runtime_transpiler_cache = this_parse.runtime_transpiler_cache,
|
.runtime_transpiler_cache = this_parse.runtime_transpiler_cache,
|
||||||
},
|
},
|
||||||
.cached => .{
|
.cached => ParseResult{
|
||||||
.ast = undefined,
|
.ast = undefined,
|
||||||
.runtime_transpiler_cache = this_parse.runtime_transpiler_cache,
|
.runtime_transpiler_cache = this_parse.runtime_transpiler_cache,
|
||||||
.source = source,
|
.source = source,
|
||||||
.loader = loader,
|
.loader = loader,
|
||||||
.input_fd = input_fd,
|
.input_fd = input_fd,
|
||||||
},
|
},
|
||||||
.already_bundled => |already_bundled| .{
|
.already_bundled => |already_bundled| ParseResult{
|
||||||
.ast = undefined,
|
.ast = undefined,
|
||||||
.already_bundled = switch (already_bundled) {
|
.already_bundled = switch (already_bundled) {
|
||||||
.bun => .source_code,
|
.bun => .source_code,
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import * as fs from "node:fs";
|
|
||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
+fs;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "commonjs"
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import * as fs from "node:fs";
|
|
||||||
console.log(eval("typeof module === 'undefined'"));
|
|
||||||
+fs;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "module"
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import { bunEnv, bunExe } from "harness";
|
|
||||||
import { join } from "path";
|
|
||||||
import { expect, test } from "bun:test";
|
|
||||||
|
|
||||||
// module type -> file extensions -> expected module type
|
|
||||||
const table = {
|
|
||||||
cjs: {
|
|
||||||
'hello.cjs': 'commonjs',
|
|
||||||
'hello.js': 'commonjs',
|
|
||||||
'hello.mjs': 'module',
|
|
||||||
'hello.ts': 'commonjs',
|
|
||||||
'hello.tsx': 'module',
|
|
||||||
'hello.cts': 'commonjs',
|
|
||||||
'hello.jsx': 'module',
|
|
||||||
'hello.mts': 'module',
|
|
||||||
// files using ES import and no exports will be detected as module
|
|
||||||
"import.cjs": "module",
|
|
||||||
},
|
|
||||||
esm: {
|
|
||||||
'hello.cjs': 'commonjs',
|
|
||||||
'hello.js': 'module',
|
|
||||||
'hello.mjs': 'module',
|
|
||||||
'hello.ts': 'module',
|
|
||||||
'hello.tsx': 'module',
|
|
||||||
'hello.cts': 'commonjs',
|
|
||||||
'hello.jsx': 'module',
|
|
||||||
'hello.mts': 'module',
|
|
||||||
// files using ES import and no exports will be detected as module
|
|
||||||
"import.cjs": "module",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
test("detect module type", () => {
|
|
||||||
const expected = Object.entries(table).map(([moduleType, extensions]) => {
|
|
||||||
return Object.entries(extensions).map(([extension, expected]) => {
|
|
||||||
return `${moduleType} ${extension} -> ${expected}`;
|
|
||||||
});
|
|
||||||
}).flat();
|
|
||||||
|
|
||||||
const actual = Object.entries(table).map(([moduleType, extensions]) => {
|
|
||||||
return Object.entries(extensions).map(([extension, expected]) => {
|
|
||||||
const proc = Bun.spawnSync({
|
|
||||||
cmd: [bunExe(), "run", join(import.meta.dir, 'module-type-fixture', moduleType, extension)],
|
|
||||||
env: bunEnv,
|
|
||||||
});
|
|
||||||
if (proc.exitCode !== 0) {
|
|
||||||
throw new Error(`Failed to run ${moduleType} ${extension}: ${proc.stderr.toString('utf8').trim()}`);
|
|
||||||
}
|
|
||||||
return `${moduleType} ${extension} -> ${proc.stdout.toString('utf8').trim() === "false" ? "commonjs" : "module"}`;
|
|
||||||
});
|
|
||||||
}).flat();
|
|
||||||
|
|
||||||
expect(actual).toEqual(expected);
|
|
||||||
});
|
|
||||||
@@ -27,7 +27,7 @@ const words: Record<string, { reason: string; limit?: number; regex?: boolean }>
|
|||||||
"alloc.ptr !=": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" },
|
"alloc.ptr !=": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" },
|
||||||
"== alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" },
|
"== alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" },
|
||||||
"!= alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" },
|
"!= alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" },
|
||||||
[String.raw`: [a-zA-Z0-9_\.\*\?\[\]\(\)]+ = undefined,`]: { reason: "Do not default a struct field to undefined", limit: 244, regex: true },
|
[String.raw`: [a-zA-Z0-9_\.\*\?\[\]\(\)]+ = undefined,`]: { reason: "Do not default a struct field to undefined", limit: 246, regex: true },
|
||||||
"usingnamespace": { reason: "This brings Bun away from incremental / faster compile times.", limit: 494 },
|
"usingnamespace": { reason: "This brings Bun away from incremental / faster compile times.", limit: 494 },
|
||||||
};
|
};
|
||||||
const words_keys = [...Object.keys(words)];
|
const words_keys = [...Object.keys(words)];
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
module.exports = 'fail'
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
module.exports = 'a unmodified';
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{ "hello": "world" }
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
declare const y: string;
|
|
||||||
enum J { x = "hello " }
|
|
||||||
const hello: string = "world";
|
|
||||||
module.exports = J.x + hello!;
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{ "hello
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
module.exports = 'c dot custom'
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
module.exports = 'd.js'
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
declare const y: string;
|
|
||||||
enum J { x = "hello" }
|
|
||||||
const hello: string = " world";
|
|
||||||
module.exports = J.x + hello!;
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
import { test, mock, expect } from "bun:test";
|
|
||||||
import path from "path";
|
|
||||||
|
|
||||||
test("require.extensions shape makes sense", () => {
|
|
||||||
const extensions = require.extensions;
|
|
||||||
expect(extensions).toBeDefined();
|
|
||||||
expect(typeof extensions).toBe("object");
|
|
||||||
expect(extensions[".js"]).toBeFunction();
|
|
||||||
expect(extensions[".json"]).toBeFunction();
|
|
||||||
expect(extensions[".node"]).toBeFunction();
|
|
||||||
// When --experimental-strip-types is passed, TypeScript files can be loaded.
|
|
||||||
expect(extensions[".cts"]).toBeFunction();
|
|
||||||
expect(extensions[".ts"]).toBeFunction();
|
|
||||||
expect(extensions[".mjs"]).toBeFunction();
|
|
||||||
expect(extensions[".mts"]).toBeFunction();
|
|
||||||
});
|
|
||||||
test("custom require extension 1", () => {
|
|
||||||
const custom = require.extensions['.custom'] = mock(function (module, filename) {
|
|
||||||
expect(filename).toBe(path.join(import.meta.dir, 'extensions-fixture', 'c.custom'));
|
|
||||||
(module as any)._compile(`module.exports = 'custom';`, filename);
|
|
||||||
});
|
|
||||||
const mod = require('./extensions-fixture/c');
|
|
||||||
expect(mod).toBe('custom');
|
|
||||||
expect(custom.mock.calls.length).toBe(1);
|
|
||||||
delete require.extensions['.custom'];
|
|
||||||
expect(() => require('./extensions-fixture/c')).toThrow(/Cannot find module/);
|
|
||||||
expect(require('./extensions-fixture/c.custom')).toBe('custom'); // already loaded
|
|
||||||
delete require.cache[require.resolve('./extensions-fixture/c.custom')];
|
|
||||||
expect(custom.mock.calls.length).toBe(1);
|
|
||||||
expect(require('./extensions-fixture/c.custom')).toBe('c dot custom'); // use js loader
|
|
||||||
});
|
|
||||||
test("custom require extension overwrite default loader", () => {
|
|
||||||
const original = require.extensions['.js'];
|
|
||||||
try {
|
|
||||||
const custom = require.extensions['.js'] = mock(function (module, filename) {
|
|
||||||
expect(filename).toBe(path.join(import.meta.dir, 'extensions-fixture', 'd.js'));
|
|
||||||
(module as any)._compile(`module.exports = 'custom';`, filename);
|
|
||||||
});
|
|
||||||
const mod = require('./extensions-fixture/d');
|
|
||||||
expect(mod).toBe('custom');
|
|
||||||
expect(custom.mock.calls.length).toBe(1);
|
|
||||||
require.extensions['.js'] = original;
|
|
||||||
expect(require('./extensions-fixture/d')).toBe('custom'); // already loaded
|
|
||||||
delete require.cache[require.resolve('./extensions-fixture/d')];
|
|
||||||
expect(custom.mock.calls.length).toBe(1);
|
|
||||||
expect(require('./extensions-fixture/d')).toBe('d.js'); // use js loader
|
|
||||||
} finally {
|
|
||||||
require.extensions['.js'] = original;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
test("custom require extension overwrite default loader with other default loader", () => {
|
|
||||||
const original = require.extensions['.js'];
|
|
||||||
try {
|
|
||||||
require.extensions['.js'] = require.extensions['.ts']!;
|
|
||||||
const mod = require('./extensions-fixture/e.js'); // should not enter JS
|
|
||||||
expect(mod).toBe('hello world');
|
|
||||||
} finally {
|
|
||||||
require.extensions['.js'] = original;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
test("test that assigning properties weirdly wont do anything bad", () => {
|
|
||||||
const original = require.extensions['.js'];
|
|
||||||
try {
|
|
||||||
function f1() {}
|
|
||||||
function f2() {}
|
|
||||||
require.extensions['.js'] = f1;
|
|
||||||
require.extensions['.abc'] = f2;
|
|
||||||
require.extensions['.js'] = f2;
|
|
||||||
require.extensions['.js'] = undefined;
|
|
||||||
require.extensions['.abc'] = undefined;
|
|
||||||
require.extensions['.abc'] = f1;
|
|
||||||
require.extensions['.js'] = f2;
|
|
||||||
} finally {
|
|
||||||
require.extensions['.js'] = original;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Refs: https://github.com/nodejs/node/issues/4778
|
|
||||||
|
|
||||||
const common = require('../common');
|
|
||||||
const assert = require('assert');
|
|
||||||
const fs = require('fs');
|
|
||||||
const Module = require('module');
|
|
||||||
const tmpdir = require('../common/tmpdir');
|
|
||||||
const file = tmpdir.resolve('test-extensions.foo.bar');
|
|
||||||
const dotfile = tmpdir.resolve('.bar');
|
|
||||||
const dotfileWithExtension = tmpdir.resolve('.foo.bar');
|
|
||||||
|
|
||||||
tmpdir.refresh();
|
|
||||||
fs.writeFileSync(file, 'console.log(__filename);', 'utf8');
|
|
||||||
fs.writeFileSync(dotfile, 'console.log(__filename);', 'utf8');
|
|
||||||
fs.writeFileSync(dotfileWithExtension, 'console.log(__filename);', 'utf8');
|
|
||||||
|
|
||||||
{
|
|
||||||
require.extensions['.bar'] = common.mustNotCall();
|
|
||||||
require.extensions['.foo.bar'] = common.mustCall();
|
|
||||||
const modulePath = tmpdir.resolve('test-extensions');
|
|
||||||
require(modulePath);
|
|
||||||
require(file);
|
|
||||||
delete require.cache[file];
|
|
||||||
delete require.extensions['.bar'];
|
|
||||||
delete require.extensions['.foo.bar'];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
require.extensions['.foo.bar'] = common.mustCall();
|
|
||||||
const modulePath = tmpdir.resolve('test-extensions');
|
|
||||||
require(modulePath);
|
|
||||||
assert.throws(
|
|
||||||
() => require(`${modulePath}.foo`),
|
|
||||||
(err) => err.message.startsWith(`Cannot find module '${modulePath}.foo'`)
|
|
||||||
);
|
|
||||||
require(`${modulePath}.foo.bar`);
|
|
||||||
delete require.cache[file];
|
|
||||||
delete require.extensions['.foo.bar'];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const modulePath = tmpdir.resolve('test-extensions');
|
|
||||||
assert.throws(
|
|
||||||
() => require(modulePath),
|
|
||||||
(err) => err.message.startsWith(`Cannot find module '${modulePath}'`)
|
|
||||||
);
|
|
||||||
delete require.cache[file];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
require.extensions['.bar'] = common.mustNotCall();
|
|
||||||
require.extensions['.foo.bar'] = common.mustCall();
|
|
||||||
const modulePath = tmpdir.resolve('test-extensions.foo');
|
|
||||||
require(modulePath);
|
|
||||||
delete require.cache[file];
|
|
||||||
delete require.extensions['.bar'];
|
|
||||||
delete require.extensions['.foo.bar'];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
require.extensions['.foo.bar'] = common.mustNotCall();
|
|
||||||
const modulePath = tmpdir.resolve('test-extensions.foo');
|
|
||||||
assert.throws(
|
|
||||||
() => require(modulePath),
|
|
||||||
(err) => err.message.startsWith(`Cannot find module '${modulePath}'`)
|
|
||||||
);
|
|
||||||
delete require.extensions['.foo.bar'];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
require.extensions['.bar'] = common.mustNotCall();
|
|
||||||
require(dotfile);
|
|
||||||
delete require.cache[dotfile];
|
|
||||||
delete require.extensions['.bar'];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
require.extensions['.bar'] = common.mustCall();
|
|
||||||
require.extensions['.foo.bar'] = common.mustNotCall();
|
|
||||||
require(dotfileWithExtension);
|
|
||||||
delete require.cache[dotfileWithExtension];
|
|
||||||
delete require.extensions['.bar'];
|
|
||||||
delete require.extensions['.foo.bar'];
|
|
||||||
Module._pathCache = { __proto__: null };
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user