require.resolve with paths option (#18851)

This commit is contained in:
chloe caruso
2025-04-08 14:07:03 -07:00
committed by GitHub
parent 5fa14574a6
commit 5f9f200e7e
17 changed files with 588 additions and 466 deletions

View File

@@ -41,8 +41,11 @@ JSC_DECLARE_HOST_FUNCTION(jsFunctionWrap);
JSC_DECLARE_CUSTOM_GETTER(getterRequireFunction);
JSC_DECLARE_CUSTOM_SETTER(setterRequireFunction);
// This is a mix of bun's builtin module names and also the ones reported by
// node v20.4.0
// This is a list of builtin module names that do not have the node prefix. It
// also includes Bun's builtin modules, as well as Bun's thirdparty overrides.
// The reason for overstuffing this list is so that uses that use these as the
// 'external' option to a bundler will properly exclude things like 'ws' which
// only work with Bun's native 'ws' implementation and not the JS one on NPM.
static constexpr ASCIILiteral builtinModuleNames[] = {
"_http_agent"_s,
"_http_client"_s,
@@ -88,7 +91,6 @@ static constexpr ASCIILiteral builtinModuleNames[] = {
"inspector/promises"_s,
"module"_s,
"net"_s,
"node:test"_s,
"os"_s,
"path"_s,
"path/posix"_s,
@@ -409,16 +411,9 @@ JSC_DEFINE_CUSTOM_SETTER(setNodeModuleResolveFilename,
return true;
}
extern "C" bool ModuleLoader__isBuiltin(const char* data, size_t len);
struct Parent {
JSArray* paths;
JSString* filename;
};
Parent getParent(VM& vm, JSGlobalObject* global, JSValue maybe_parent)
PathResolveModule getParent(VM& vm, JSGlobalObject* global, JSValue maybe_parent)
{
Parent value { nullptr, nullptr };
PathResolveModule value { nullptr, nullptr, false };
if (!maybe_parent) {
return value;
@@ -461,8 +456,15 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveLookupPaths,
return JSC::JSValue::encode(JSC::jsNull());
}
auto parent = getParent(vm, globalObject, callFrame->argument(1));
PathResolveModule parent = getParent(vm, globalObject, callFrame->argument(1));
RETURN_IF_EXCEPTION(scope, {});
RELEASE_AND_RETURN(scope, JSC::JSValue::encode(resolveLookupPaths(globalObject, request, parent)));
}
JSC::JSValue resolveLookupPaths(JSC::JSGlobalObject* globalObject, String request, PathResolveModule parent)
{
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
// Check for node modules paths.
if (request.characterAt(0) != '.' || (request.length() > 1 && request.characterAt(1) != '.' && request.characterAt(1) != '/' &&
@@ -472,16 +474,24 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveLookupPaths,
true
#endif
)) {
auto array = JSC::constructArray(
globalObject, (ArrayAllocationProfile*)nullptr, nullptr, 0);
if (parent.paths) {
auto array = JSC::constructArray(globalObject, (ArrayAllocationProfile*)nullptr, nullptr, 0);
auto len = parent.paths->length();
for (size_t i = 0; i < len; i++) {
auto path = parent.paths->getIndex(globalObject, i);
array->push(globalObject, path);
}
RELEASE_AND_RETURN(scope, array);
} else if (parent.pathsArrayLazy && parent.filename) {
auto filenameValue = parent.filename->value(globalObject);
RETURN_IF_EXCEPTION(scope, {});
auto filename = Bun::toString(filenameValue);
auto paths = JSValue::decode(Resolver__nodeModulePathsJSValue(filename, globalObject, true));
RELEASE_AND_RETURN(scope, paths);
} else {
auto array = JSC::constructEmptyArray(globalObject, nullptr, 0);
RELEASE_AND_RETURN(scope, array);
}
return JSValue::encode(array);
}
JSValue dirname;
@@ -499,9 +509,8 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveLookupPaths,
}
JSValue values[] = { dirname };
auto array = JSC::constructArray(
globalObject, (ArrayAllocationProfile*)nullptr, values, 1);
RELEASE_AND_RETURN(scope, JSValue::encode(array));
auto array = JSC::constructArray(globalObject, (ArrayAllocationProfile*)nullptr, values, 1);
RELEASE_AND_RETURN(scope, array);
}
extern "C" JSC::EncodedJSValue NodeModuleModule__findPath(JSGlobalObject*,