aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/javascript.zig
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-02-28 00:01:21 -0800
committerGravatar GitHub <noreply@github.com> 2023-02-28 00:01:21 -0800
commitec7929b251b91745f676ce85f173516186f36c6e (patch)
tree7b1e0378f20526a1236dab54c129a0105ffdfc83 /src/bun.js/javascript.zig
parent590219966edc9e79b34ab2c073ae34d14baa141a (diff)
downloadbun-ec7929b251b91745f676ce85f173516186f36c6e.tar.gz
bun-ec7929b251b91745f676ce85f173516186f36c6e.tar.zst
bun-ec7929b251b91745f676ce85f173516186f36c6e.zip
Implement `preload` support (like `node -r ` except in a config file) (#2231)
* Update Makefile * Introduce `preload` * Add a test * Support entry points --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src/bun.js/javascript.zig')
-rw-r--r--src/bun.js/javascript.zig77
1 files changed, 74 insertions, 3 deletions
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index efa42deb5..445f30233 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -361,6 +361,7 @@ pub const VirtualMachine = struct {
timer: Bun.Timer = Bun.Timer{},
uws_event_loop: ?*uws.Loop = null,
pending_unref_counter: i32 = 0,
+ preload: []const string = &[_][]const u8{},
/// hide bun:wrap from stack traces
/// bun:wrap is very noisy
@@ -990,8 +991,7 @@ pub const VirtualMachine = struct {
)) {
.success => |r| r,
.failure => |e| e,
- .pending => unreachable,
- .not_found => if (!retry_on_not_found)
+ .pending, .not_found => if (!retry_on_not_found)
error.ModuleNotFound
else {
retry_on_not_found = false;
@@ -1441,7 +1441,12 @@ pub const VirtualMachine = struct {
pub fn reloadEntryPoint(this: *VirtualMachine, entry_path: []const u8) !*JSInternalPromise {
this.main = entry_path;
- try this.entry_point.generate(this.bun_watcher != null, Fs.PathName.init(entry_path), main_file_name);
+ try this.entry_point.generate(
+ this.allocator,
+ this.bun_watcher != null,
+ Fs.PathName.init(entry_path),
+ main_file_name,
+ );
this.eventLoop().ensureWaker();
var promise: *JSInternalPromise = undefined;
@@ -1460,6 +1465,72 @@ pub const VirtualMachine = struct {
return promise;
}
+ for (this.preload) |preload| {
+ var result = switch (this.bundler.resolver.resolveAndAutoInstall(
+ this.bundler.fs.top_level_dir,
+ normalizeSource(preload),
+ .stmt,
+ .read_only,
+ )) {
+ .success => |r| r,
+ .failure => |e| {
+ this.log.addErrorFmt(
+ null,
+ logger.Loc.Empty,
+ this.allocator,
+ "{s} resolving preload {any}",
+ .{
+ @errorName(e),
+ js_printer.formatJSONString(preload),
+ },
+ ) catch unreachable;
+ return e;
+ },
+ .pending, .not_found => {
+ this.log.addErrorFmt(
+ null,
+ logger.Loc.Empty,
+ this.allocator,
+ "preload not found {any}",
+ .{
+ js_printer.formatJSONString(preload),
+ },
+ ) catch unreachable;
+ return error.ModuleNotFound;
+ },
+ };
+ promise = JSModuleLoader.loadAndEvaluateModule(this.global, &ZigString.init(result.path().?.text));
+ this.pending_internal_promise = promise;
+
+ // pending_internal_promise can change if hot module reloading is enabled
+ if (this.bun_watcher != null) {
+ this.eventLoop().performGC();
+ switch (this.pending_internal_promise.status(this.global.vm())) {
+ JSC.JSPromise.Status.Pending => {
+ while (this.pending_internal_promise.status(this.global.vm()) == .Pending) {
+ this.eventLoop().tick();
+
+ if (this.pending_internal_promise.status(this.global.vm()) == .Pending) {
+ this.eventLoop().autoTick();
+ }
+ }
+ },
+ else => {},
+ }
+ } else {
+ this.eventLoop().performGC();
+ this.waitForPromise(JSC.AnyPromise{
+ .Internal = promise,
+ });
+ }
+
+ if (promise.status(this.global.vm()) == .Rejected)
+ return promise;
+ }
+
+ // only load preloads once
+ this.preload.len = 0;
+
promise = JSModuleLoader.loadAndEvaluateModule(this.global, ZigString.static(main_file_name));
this.pending_internal_promise = promise;
} else {