aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-08-06 18:06:18 -0700
committerGravatar GitHub <noreply@github.com> 2023-08-06 18:06:18 -0700
commit8297fb0d2f28ff8bd3fe3bf1383d704420e73a38 (patch)
treeb63abf4db9e7af725349984b7759e6a8ffcdfb10
parent04925bb94c12a7c961bb758d2e2f3ecbe091fff0 (diff)
downloadbun-8297fb0d2f28ff8bd3fe3bf1383d704420e73a38.tar.gz
bun-8297fb0d2f28ff8bd3fe3bf1383d704420e73a38.tar.zst
bun-8297fb0d2f28ff8bd3fe3bf1383d704420e73a38.zip
Bind require.resolve() (#4030)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
-rw-r--r--src/js/builtins/Module.ts4
-rw-r--r--src/js/out/WebCoreJSBuiltins.cpp4
-rw-r--r--src/js_parser.zig44
-rw-r--r--test/cli/run/require-cache-fixture.cjs8
4 files changed, 47 insertions, 13 deletions
diff --git a/src/js/builtins/Module.ts b/src/js/builtins/Module.ts
index 5cf7290ae..d6ebc8578 100644
--- a/src/js/builtins/Module.ts
+++ b/src/js/builtins/Module.ts
@@ -81,8 +81,8 @@ export function require(this: CommonJSModuleRecord, id: string) {
return mod.exports;
}
-export function requireResolve(this: CommonJSModuleRecord, id: string) {
- return $resolveSync(id, this.path, false);
+export function requireResolve(this: string | { path: string }, id: string) {
+ return $resolveSync(id, typeof this === "string" ? this : this?.path, false);
}
export function requireNativeModule(id: string) {
diff --git a/src/js/out/WebCoreJSBuiltins.cpp b/src/js/out/WebCoreJSBuiltins.cpp
index a9039b0f2..f3568455b 100644
--- a/src/js/out/WebCoreJSBuiltins.cpp
+++ b/src/js/out/WebCoreJSBuiltins.cpp
@@ -722,9 +722,9 @@ const char* const s_moduleRequireCode = "(function (id){\"use strict\";const exi
const JSC::ConstructAbility s_moduleRequireResolveCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_moduleRequireResolveCodeConstructorKind = JSC::ConstructorKind::None;
const JSC::ImplementationVisibility s_moduleRequireResolveCodeImplementationVisibility = JSC::ImplementationVisibility::Public;
-const int s_moduleRequireResolveCodeLength = 67;
+const int s_moduleRequireResolveCodeLength = 96;
static const JSC::Intrinsic s_moduleRequireResolveCodeIntrinsic = JSC::NoIntrinsic;
-const char* const s_moduleRequireResolveCode = "(function (id){\"use strict\";return @resolveSync(id,this.path,!1)})\n";
+const char* const s_moduleRequireResolveCode = "(function (id){\"use strict\";return @resolveSync(id,typeof this===\"string\"\?this:this\?.path,!1)})\n";
// requireNativeModule
const JSC::ConstructAbility s_moduleRequireNativeModuleCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
diff --git a/src/js_parser.zig b/src/js_parser.zig
index 392d7d922..2ce10a77d 100644
--- a/src/js_parser.zig
+++ b/src/js_parser.zig
@@ -21186,7 +21186,7 @@ fn NewParser_(
logger.Loc.Empty,
);
const cjsGlobal = p.newSymbol(.unbound, "$_BunCommonJSModule_$") catch unreachable;
- var all_call_args = allocator.alloc(Expr, 7) catch unreachable;
+ var all_call_args = allocator.alloc(Expr, 8) catch unreachable;
const this_module = p.newExpr(
E.Dot{
.name = "module",
@@ -21195,9 +21195,19 @@ fn NewParser_(
},
logger.Loc.Empty,
);
- var call_args = all_call_args[1..];
+
var bind_args = all_call_args[0..1];
bind_args[0] = this_module;
+ var bind_resolve_args = all_call_args[1..2];
+ var call_args = all_call_args[2..];
+
+ const module_id = p.newExpr(E.Dot{
+ .name = "id",
+ .target = this_module,
+ .name_loc = logger.Loc.Empty,
+ }, logger.Loc.Empty);
+
+ bind_resolve_args[0] = module_id;
const get_require = p.newExpr(
E.Dot{
.name = "require",
@@ -21219,12 +21229,24 @@ fn NewParser_(
logger.Loc.Empty,
);
- const module_id = p.newExpr(E.Dot{
- .name = "id",
- .target = this_module,
+ const get_resolve = p.newExpr(E.Dot{
+ .name = "resolve",
.name_loc = logger.Loc.Empty,
+ .target = get_require,
}, logger.Loc.Empty);
+ const create_resolve_binding = p.newExpr(
+ E.Call{
+ .target = p.newExpr(E.Dot{
+ .name = "bind",
+ .name_loc = logger.Loc.Empty,
+ .target = get_resolve,
+ }, logger.Loc.Empty),
+ .args = bun.BabyList(Expr).init(bind_resolve_args),
+ },
+ logger.Loc.Empty,
+ );
+
const require_path = p.newExpr(
E.Dot{
.name = "path",
@@ -21242,15 +21264,25 @@ fn NewParser_(
logger.Loc.Empty,
);
+ const assign_resolve_binding = p.newExpr(
+ E.Binary{
+ .left = get_resolve,
+ .right = create_resolve_binding,
+ .op = .bin_assign,
+ },
+ logger.Loc.Empty,
+ );
+
const assign_id = p.newExpr(E.Binary{
.left = require_path,
.right = module_id,
.op = .bin_assign,
}, logger.Loc.Empty);
- var create_require = [3]Expr{
+ var create_require = [4]Expr{
assign_binding,
assign_id,
+ assign_resolve_binding,
get_require,
};
diff --git a/test/cli/run/require-cache-fixture.cjs b/test/cli/run/require-cache-fixture.cjs
index 838be9ceb..69f8cebeb 100644
--- a/test/cli/run/require-cache-fixture.cjs
+++ b/test/cli/run/require-cache-fixture.cjs
@@ -27,13 +27,15 @@ const foo = require("./require-cache-fixture-b.cjs");
exports.foo = foo;
-if (require.cache[require.resolve("./require-cache-fixture-b.cjs")].exports !== exports.foo) {
+var res = require.resolve;
+
+if (require.cache[res("./require-cache-fixture-b.cjs")].exports !== exports.foo) {
throw new Error("exports.foo !== require.cache[require.resolve('./require-cache-fixture-b')]");
}
Bun.gc(true);
-delete require.cache[require.resolve("./require-cache-fixture-b.cjs")];
+delete require.cache[res("./require-cache-fixture-b.cjs")];
Bun.gc(true);
@@ -41,7 +43,7 @@ exports.bar = require("./require-cache-fixture-b.cjs");
Bun.gc(true);
-if (require.cache[require.resolve("./require-cache-fixture-b.cjs")].exports !== exports.bar) {
+if (require.cache[res("./require-cache-fixture-b.cjs")].exports !== exports.bar) {
throw new Error("exports.bar !== require.cache[require.resolve('./require-cache-fixture-b')]");
}