Skip to content

Commit ba7204d

Browse files
refactor(examples): refactor example instructions
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
1 parent 3e9d4b5 commit ba7204d

File tree

13 files changed

+189
-23
lines changed

13 files changed

+189
-23
lines changed

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: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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`](./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 ([`hello.js`](./hello.js))
28+
looks like the following:
29+
30+
```js
31+
export function hello (name) {
32+
return `Hello ${name}`;
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+
We call the produced WebAssembly component "guest" as it is code that will run on
44+
the WebAssembly virtual machine/runtime.
45+
46+
[wit]: https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md
47+
48+
## `host` - A WebAssembly runtime embedding written in Rust
49+
50+
Since our component does not export a standardized way to run it (in this case,
51+
the standard we *could* have used would be [WASI CLI][wasi-cli]), we must use a custom host which
52+
embeds a WebAssembly runtime ([`wasmtime`][wasmtime] in this case) to run the WebAssembly Component.
53+
54+
`wasmtime` is easiest to use from [Rust][rust], so we have the `host` that contains
55+
setup code which enables use of the component we wrote, and calls it.
56+
57+
See [`host/src/main.rs`](./host/src/main.rs) for the full code listing.
58+
59+
[wasmtime]: https://github.com/bytecodealliance/wasmtime
60+
[wasi-cli]: https://github.com/WebAssembly/wasi-cli
61+
[rust]: https://rust-lang.org
62+
63+
## Build the component
64+
65+
To build the WebAssembly component, enter the `guest` directory and install dependencies:
66+
67+
```console
68+
npm install
69+
```
70+
71+
Then either run the `componentize.js` script directly:
72+
73+
```console
74+
node componentize.js
75+
```
76+
77+
Or use the pre-configured `build` script:
78+
79+
```console
80+
npm run build
81+
```
82+
83+
## Run the component
84+
85+
### Via automation
86+
87+
To run the component and test it's output, use the included bash script:
88+
89+
```console
90+
./test.sh
91+
```
92+
93+
### Manually
94+
95+
To run the component manually, we must run our custom `wasmtime` embedding manually.
96+
97+
First enter the `host` directory and use `cargo run`:
98+
99+
```console
100+
cargo run
101+
```
102+
103+
## Common Issues
104+
105+
### No such file or directory
106+
107+
If you get an error that looks like the following:
108+
109+
```
110+
thread 'main' panicked at src/main.rs:39:67:
111+
called `Result::unwrap()` on an `Err` value: failed to read from `../../guest/hello.component.wasm`
112+
113+
Caused by:
114+
No such file or directory (os error 2)
115+
```
116+
117+
This means that the default path (which is relative, and embedded in the binary) to the component
118+
produced by the `guest` is not present.
119+
120+
To fix this, specify `COMPONENT_WASM_PATH` as an environment variable before `cargo run`:
121+
122+
```console
123+
COMPONENT_WASM_PATH=/absolute/path/to/hello.component.wasm cargo run
124+
```
125+
126+
If you're running the produced `wasmtime-test` binary itself:
127+
128+
```console
129+
COMPONENT_WASM_PATH=/absolute/path/to/hello.component.wasm path/to/wasmtime-test
130+
```

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)