diff --git a/packages/gems/js/lib/js/require_remote.rb b/packages/gems/js/lib/js/require_remote.rb
index 5c9946cf45..e70dcedf79 100644
--- a/packages/gems/js/lib/js/require_remote.rb
+++ b/packages/gems/js/lib/js/require_remote.rb
@@ -43,11 +43,27 @@ class RequireRemote
include Singleton
def initialize
+ # By default, the base_url is the URL of the HTML file that invoked ruby.wasm vm.
base_url = JS.global[:URL].new(JS.global[:location][:href])
@resolver = URLResolver.new(base_url)
@evaluator = Evaluator.new
end
+ # If you want to resolve relative paths to a starting point other than the HTML file that executes ruby.wasm,
+ # you can set the base_url property.
+ # For example, if you want to use the `lib` directory as the starting point, specify base_url as follows
+ #
+ # == Example
+ # require 'js/require_remote'
+ # JS::RequireRemote.instance.base_url = "lib"
+ # JS::RequireRemote.instance.load("foo") # => 'lib/foo.rb' will be loaded.
+ #
+ def base_url=(base_url)
+ base_url = base_url.end_with?("/") ? base_url : "#{base_url}/"
+ url = JS.global[:URL].new(base_url, JS.global[:location][:href])
+ @resolver = URLResolver.new(url)
+ end
+
# Load the given feature from remote.
def load(relative_feature)
location = @resolver.get_location(relative_feature)
diff --git a/packages/gems/js/lib/js/require_remote/url_resolver.rb b/packages/gems/js/lib/js/require_remote/url_resolver.rb
index 7bbaae095c..6a0052c686 100644
--- a/packages/gems/js/lib/js/require_remote/url_resolver.rb
+++ b/packages/gems/js/lib/js/require_remote/url_resolver.rb
@@ -26,6 +26,10 @@ def pop()
@url_stack.pop
end
+ def inspect
+ "#{self.class}(#{@url_stack})"
+ end
+
private
def filename_from(relative_feature)
diff --git a/packages/npm-packages/ruby-wasm-wasi/test-e2e/integrations/js-require-remote.spec.ts b/packages/npm-packages/ruby-wasm-wasi/test-e2e/integrations/js-require-remote.spec.ts
index 2bd1e0ed17..1cbe00bf7d 100644
--- a/packages/npm-packages/ruby-wasm-wasi/test-e2e/integrations/js-require-remote.spec.ts
+++ b/packages/npm-packages/ruby-wasm-wasi/test-e2e/integrations/js-require-remote.spec.ts
@@ -115,5 +115,25 @@ if (!process.env.RUBY_NPM_PACKAGE_ROOT) {
expect(await resolve()).toBe("Hello from RecursiveRequire::B");
});
+
+ test("JS::RequireRemote#load loads the file with a path relative to the base_url specified by the base_url property.", async ({
+ page,
+ }) => {
+ const resolve = await resolveBinding(page, "checkResolved");
+ await page.goto(
+ "https://cdn.jsdelivr.net/npm/@ruby/head-wasm-wasi@latest/dist/",
+ );
+ await page.setContent(`
+
+
+ `);
+
+ expect(await resolve()).toBe("Hello from RecursiveRequire::B");
+ });
});
}