Skip to content

Commit d8dd995

Browse files
refactor(examples): refactor example instructions (#175)
1 parent d158e75 commit d8dd995

File tree

14 files changed

+198
-25
lines changed

14 files changed

+198
-25
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ jobs:
280280
key: output-example-jit-cargo-${{ hashFiles('example/src/main.rs', 'example/Cargo.lock', 'example/hello.wit') }}
281281

282282
- name: Test Example
283-
run: cd example && npm run build && ./test.sh
283+
working-directory: examples/hello-world
284+
run: bash test.sh
284285

285286
test-aot:
286287
runs-on: ubuntu-latest
@@ -349,4 +350,5 @@ jobs:
349350
key: output-example-aot-cargo-${{ hashFiles('example/src/main.rs', 'example/Cargo.lock', 'example/hello.wit') }}
350351

351352
- name: Test Example
352-
run: cd example && npm run build && ./test.sh
353+
working-directory: examples/hello-world
354+
run: bash test.sh

example/README.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

example/test.sh

Lines changed: 0 additions & 4 deletions
This file was deleted.

examples/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Examples
2+
3+
This folder contains example projects that use `componentize-js`.

examples/hello-world/README.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Example Javascript component
2+
3+
This folder contains an example Javascript project that uses `componentize-js`
4+
as a library to build a basic [WebAssembly component][cm-book].
5+
6+
[cm-book]: https://component-model.bytecodealliance.org/
7+
8+
## Overview
9+
10+
This folder contains *two* codebases:
11+
12+
- `guest` contains the Javascript WebAssembly Component
13+
- `host` contains a Rust host that has been configured to run the component
14+
15+
### `guest` - A WebAssembly component written in Javascript
16+
17+
The [WebAssembly Interface Types ("WIT")][wit] interface ([`hello.wit`](./guest/hello.wit)) for the component is:
18+
19+
```wit
20+
package local:hello;
21+
22+
world component {
23+
export hello: func(name: string) -> string;
24+
}
25+
```
26+
27+
A Javascript (ES) module that conforms to the interface shown above looks like the following:
28+
29+
```js
30+
export function hello (name) {
31+
return `Hello ${name}`;
32+
}
33+
```
34+
35+
> [!NOTE]
36+
> The ES module is assumed implicitly to *be* the targeted `world`.
37+
>
38+
> This means that the JS export of the `hello` function maps to the
39+
> WIT `hello` `export` of the `component` world.
40+
>
41+
> The world does not have to be called `component`.
42+
43+
See [`hello.js`](./guest/hello.js) for the full code listing.
44+
45+
We call the produced WebAssembly component "guest" as it is code that will run on
46+
the WebAssembly virtual machine/runtime.
47+
48+
[wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md
49+
50+
## `host` - A WebAssembly runtime embedding written in Rust
51+
52+
Since our component does not export a standardized way to run it (in this case,
53+
the standard we *could* have used would be [WASI CLI][wasi-cli]), we must use a custom host which
54+
embeds a WebAssembly runtime ([`wasmtime`][wasmtime] in this case) to run the WebAssembly Component.
55+
56+
`wasmtime` is easiest to use from [Rust][rust], so we have the `host` that contains
57+
setup code which enables use of the component we wrote, and calls it.
58+
59+
See [`host/src/main.rs`](./host/src/main.rs) for the full code listing.
60+
61+
[wasmtime]: https://github.com/bytecodealliance/wasmtime
62+
[wasi-cli]: https://github.com/WebAssembly/wasi-cli
63+
[rust]: https://rust-lang.org
64+
65+
## Build the component
66+
67+
To build the WebAssembly component, enter the `guest` directory and install dependencies:
68+
69+
```console
70+
npm install
71+
```
72+
73+
Then either run the `componentize.js` script directly:
74+
75+
```console
76+
node componentize.js
77+
```
78+
79+
Or use the pre-configured `build` script:
80+
81+
```console
82+
npm run build
83+
```
84+
85+
## Run the component
86+
87+
### Via automation
88+
89+
To run the component and test it's output, use the included bash script:
90+
91+
```console
92+
./test.sh
93+
```
94+
95+
### Manually
96+
97+
To run the component manually, we must run our custom `wasmtime` embedding manually.
98+
99+
First enter the `host` directory and use `cargo run`:
100+
101+
```console
102+
cargo run
103+
```
104+
105+
## Common Issues
106+
107+
### No such file or directory
108+
109+
If you get an error that looks like the following:
110+
111+
```
112+
thread 'main' panicked at src/main.rs:39:67:
113+
called `Result::unwrap()` on an `Err` value: failed to read from `../../guest/hello.component.wasm`
114+
115+
Caused by:
116+
No such file or directory (os error 2)
117+
```
118+
119+
This means that the default path (which is relative, and embedded in the binary) to the component
120+
produced by the `guest` is not present.
121+
122+
To fix this, specify `COMPONENT_WASM_PATH` as an environment variable before `cargo run`:
123+
124+
```console
125+
COMPONENT_WASM_PATH=/absolute/path/to/hello.component.wasm cargo run
126+
```
127+
128+
If you're running the produced `wasmtime-test` binary itself:
129+
130+
```console
131+
COMPONENT_WASM_PATH=/absolute/path/to/hello.component.wasm path/to/wasmtime-test
132+
```

example/componentize.js renamed to examples/hello-world/guest/componentize.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import { componentize } from '@bytecodealliance/componentize-js';
21
import { readFile, writeFile } from 'node:fs/promises';
32
import { resolve } from 'node:path';
43

5-
const enableAot = process.env.ENABLE_AOT == '1'
4+
import { componentize } from '@bytecodealliance/componentize-js';
5+
6+
// AoT compilation makes use of weval (https://github.com/bytecodealliance/weval)
7+
const enableAot = process.env.ENABLE_AOT == '1';
68

79
const jsSource = await readFile('hello.js', 'utf8');
810

10.2 MB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package local:hello;
22

3-
world hello {
3+
world component {
44
export hello: func(name: string) -> string;
55
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
"@bytecodealliance/componentize-js": "*"
66
},
77
"scripts": {
8-
"build": "node componentize.js && cargo build --release",
9-
"test": "./target/release/wasmtime-test"
8+
"build": "node componentize.js && cargo build --release"
109
}
1110
}

0 commit comments

Comments
 (0)