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"); + }); }); }