Skip to content

Commit 8eebd6c

Browse files
committed
ruby.wasm provides JS::RequireRemote#load. The user uses this method to replace the require_relative method.
1 parent 7bfcacf commit 8eebd6c

File tree

4 files changed

+35
-45
lines changed

4 files changed

+35
-45
lines changed

ext/js/lib/js/require_remote.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require "singleton"
2+
require "js"
23
require_relative "./url_resolver"
34

45
module JS
@@ -11,7 +12,11 @@ def initialize
1112
set_base_url
1213
end
1314

14-
def require_relative(relative_feature)
15+
# Load the given feature from remote.
16+
# The use_maps parameter is not used.
17+
# This is a parameter to keep the method name unchanged when supporting require methods.
18+
# Maps like import maps will be used.
19+
def load(relative_feature, use_maps: false)
1520
location = get_location(relative_feature)
1621
response = JS.global.fetch(location.url).await
1722

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
11
<html>
22
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/browser.script.iife.js"></script>
33
<script type="text/ruby" data-eval="async">
4+
# Patch require_relative to load from remote
5+
require 'js/require_remote'
6+
7+
module Kernel
8+
alias original_require_relative require_relative
9+
10+
# The require_relative may be used in the embedded Gem.
11+
# First try to load from the built-in filesystem, and if that fails,
12+
# load from the URL.
13+
def require_relative(path)
14+
caller_path = caller_locations(1, 1).first.absolute_path || ''
15+
dir = File.dirname(caller_path)
16+
file = File.absolute_path(path, dir)
17+
18+
original_require_relative(file)
19+
rescue LoadError
20+
JS::RequireRemote.instance.load(path)
21+
end
22+
end
23+
24+
# The above patch does not break the original require_relative
25+
require 'csv'
26+
csv = CSV.new "foo\nbar\n"
27+
28+
# Load the main script
429
require_relative 'main'
530
</script>
631
</html>

packages/npm-packages/ruby-wasm-wasi/src/browser.script.ts

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ export const main = async (pkg: { name: string; version: string }) => {
1212

1313
globalThis.rubyVM = vm;
1414

15-
patchRequireRelative(vm);
16-
1715
// Wait for the text/ruby script tag to be read.
1816
// It may take some time to read ruby+stdlib.wasm
1917
// and DOMContentLoaded has already been fired.
@@ -96,28 +94,3 @@ const compileWebAssemblyModule = async function (
9694
return WebAssembly.compileStreaming(response);
9795
}
9896
};
99-
100-
const patchRequireRelative = (vm: RubyVM) => {
101-
const patch = `
102-
require 'js'
103-
require 'js/require_remote'
104-
105-
module Kernel
106-
alias original_require_relative require_relative
107-
108-
# The require_relative may be used in the embedded Gem.
109-
# First try to load from the built-in filesystem, and if that fails,
110-
# load from the URL.
111-
def require_relative(path)
112-
caller_path = caller_locations(1, 1).first.absolute_path || ''
113-
dir = File.dirname(caller_path)
114-
file = File.absolute_path(path, dir)
115-
116-
original_require_relative(file)
117-
rescue LoadError
118-
JS::RequireRemote.instance.require_relative(path)
119-
end
120-
end
121-
`;
122-
vm.eval(patch);
123-
};

packages/npm-packages/ruby-wasm-wasi/test-e2e/integrations/browser-script.spec.ts

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,8 @@ if (!process.env.RUBY_NPM_PACKAGE_ROOT) {
6161
});
6262
});
6363

64-
test.describe("require_relative", () => {
65-
test("patch does not break original require_relative", async ({ page }) => {
66-
const resolve = await resolveBinding(page, "checkResolved");
67-
await page.setContent(`
68-
<script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/browser.script.iife.js">
69-
</script>
70-
<script type="text/ruby" data-eval="async">
71-
require 'csv'
72-
csv = CSV.new "foo\nbar\n"
73-
JS.global.checkResolved csv.first
74-
</script>
75-
`);
76-
expect(await resolve()).toStrictEqual(["foo"]);
77-
});
78-
79-
test("require_relative throws error when gem is not found", async ({
64+
test.describe('JS::RequireRemote#load', () => {
65+
test("JS::RequireRemote#load throws error when gem is not found", async ({
8066
page,
8167
}) => {
8268
// Opens the URL that will be used as the basis for determining the relative URL.
@@ -87,7 +73,8 @@ if (!process.env.RUBY_NPM_PACKAGE_ROOT) {
8773
<script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/browser.script.iife.js">
8874
</script>
8975
<script type="text/ruby" data-eval="async">
90-
require_relative 'foo'
76+
require 'js/require_remote'
77+
JS::RequireRemote.instance.load 'foo'
9178
</script>
9279
`);
9380
const error = await page.waitForEvent("pageerror");

0 commit comments

Comments
 (0)