mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-24 06:33:33 +03:00
Rewrite the README using Webpack
Right now Webpack probably has the most mature support for loading wasm modules, so let's show off how to do that! Additionally this commits hello world as an example to the repository.
This commit is contained in:
parent
30986dacad
commit
4aa6793b9e
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
node_modules
|
||||
package-lock.json
|
||||
|
@ -15,6 +15,7 @@ script:
|
||||
- rustup target add wasm32-unknown-unknown
|
||||
- cargo test
|
||||
- cargo install --debug --path crates/wasm-bindgen-cli
|
||||
- (cd examples/hello_world && ./build.sh)
|
||||
|
||||
notifications:
|
||||
email:
|
||||
|
@ -14,4 +14,7 @@ wasm-bindgen-macro = { path = "crates/wasm-bindgen-macro" }
|
||||
test-support = { path = "crates/test-support" }
|
||||
|
||||
[workspace]
|
||||
members = ["crates/wasm-bindgen-cli"]
|
||||
members = [
|
||||
"crates/wasm-bindgen-cli",
|
||||
"examples/hello_world",
|
||||
]
|
||||
|
103
README.md
103
README.md
@ -49,10 +49,19 @@ Let's implement the equivalent of "Hello, world!" for this crate.
|
||||
|
||||
[rustup]: https://rustup.rs
|
||||
|
||||
First up, let's add the wasm target and generate a Rust project:
|
||||
First up, let's install the tools we need
|
||||
|
||||
```
|
||||
$ rustup target add wasm32-unknown-unknown
|
||||
$ cargo install --git https://github.com/alexcrichton/wasm-bindgen
|
||||
```
|
||||
|
||||
The first command here installs the wasm target so you can compile to it, and
|
||||
the latter will install the `wasm-bindgen` CLI tool we'll be using later.
|
||||
|
||||
Next up let's make our project
|
||||
|
||||
```
|
||||
$ cargo new js-hello-world
|
||||
```
|
||||
|
||||
@ -110,15 +119,8 @@ can use [wasm-gc] to make this file a little smaller
|
||||
[wasm-gc]: https://github.com/alexcrichton/wasm-gc
|
||||
|
||||
Now that we've generated the wasm module it's time to run the bindgen tool
|
||||
itself! Let's install it:
|
||||
|
||||
```
|
||||
$ cargo install --git https://github.com/alexcrichton/wasm-bindgen
|
||||
```
|
||||
|
||||
This'll install a `wasm-bindgen` binary next to your `cargo` binary. This tool
|
||||
will postprocess the wasm file rustc generated, generating a new wasm file and a
|
||||
set of JS bindings as well. Let's invoke it!
|
||||
itself! This tool will postprocess the wasm file rustc generated, generating a
|
||||
new wasm file and a set of JS bindings as well. Let's invoke it!
|
||||
|
||||
```
|
||||
$ wasm-bindgen target/wasm32-unknown-unknown/release/js_hello_world.wasm \
|
||||
@ -135,36 +137,71 @@ module. The `js_hello_world.js` file emitted by `wasm-bindgen` should have the
|
||||
intended interface of the wasm file, notably with rich types like strings,
|
||||
classes, etc.
|
||||
|
||||
The `wasm-bindgen` tool also emits a secondary file, `js_hello_world_wasm.wasm`.
|
||||
This is the original wasm file but postprocessed a bit. It's intended that the
|
||||
`js_hello_world_wasm.wasm` file, like before, acts like an ES6 module. The
|
||||
`js_hello_world.wasm` file, for example, uses `import` to import functionality
|
||||
from the wasm.
|
||||
The `wasm-bindgen` tool also emits a few other files needed to implement this
|
||||
module. For example `js_hello_world_wasm.wasm` is the original wasm file but
|
||||
postprocessed a bit. It's intended that the `js_hello_world_wasm.wasm` file,
|
||||
like before, acts like an ES6 module. The `js_hello_world.wasm` file, for
|
||||
example, uses `import` to import functionality from the other `*_shims` file
|
||||
generated (an internal implementation detail here).
|
||||
|
||||
Note that you can also pass a `--nodejs` argument to `wasm-bindgen` for emitting
|
||||
Node-compatible JS as well as a `--typescript` argument to emit a `*.d.ts` file
|
||||
describing the exported contents.
|
||||
|
||||
At this point you'll typically plug these files into a larger build system. Both
|
||||
files emitted by `wasm-bindgen` act like normal ES6 modules (one just happens to
|
||||
At this point you'll probably plug these files into a larger build system.
|
||||
Files emitted by `wasm-bindgen` act like normal ES6 modules (one just happens to
|
||||
be wasm). As of the time of this writing there's unfortunately not a lot of
|
||||
tools that natively do this (but they're coming!). In the meantime we can use
|
||||
the `wasm2es6js` utility (aka "hack") from the `wasm-bindgen` tool we previously
|
||||
installed along with the `parcel-bundler` packager. Note that these steps will
|
||||
differ depending on your build system.
|
||||
tools that natively do this, but Webpack's 4.0 beta release has native wasm
|
||||
support!. Let's take a look at that and see how it works.
|
||||
|
||||
Alright first create an `index.js` file:
|
||||
First create an `index.js` file:
|
||||
|
||||
```js
|
||||
import { greet } from "./js_hello_world";
|
||||
import { booted } from "./js_hello_world_wasm";
|
||||
const js = import("./js_hello_world");
|
||||
|
||||
booted.then(() => {
|
||||
greet("World!");
|
||||
js.then(js => {
|
||||
js.greet("World!");
|
||||
});
|
||||
```
|
||||
|
||||
Then a corresponding `index.html`:
|
||||
Note that we're using `import(..)` here because Webpack [doesn't
|
||||
support][webpack-issue] synchronously importing modules from the main chunk just
|
||||
yet.
|
||||
|
||||
[webpack-issue]: https://github.com/webpack/webpack/issues/6615
|
||||
|
||||
Next our JS dependencies by creating a `package.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.0.1",
|
||||
"webpack-cli": "^2.0.10",
|
||||
"webpack-dev-server": "^3.1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
and our webpack configuration
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: "./index.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "index.js",
|
||||
},
|
||||
mode: "development"
|
||||
};
|
||||
```
|
||||
|
||||
Our corresponding `index.html`:
|
||||
|
||||
```html
|
||||
<html>
|
||||
@ -177,18 +214,14 @@ Then a corresponding `index.html`:
|
||||
</html>
|
||||
```
|
||||
|
||||
And run a local server with these files:
|
||||
And finally:
|
||||
|
||||
```
|
||||
# Convert `*.wasm` to `*.js` where the JS internally instantiates the wasm
|
||||
$ wasm2es6js js_hello_world_wasm.wasm -o js_hello_world_wasm.js --base64
|
||||
|
||||
# Install parcel and run it against the index files we use below.
|
||||
$ npm install -g parcel-bundler
|
||||
$ parcel index.html
|
||||
$ npm run serve
|
||||
```
|
||||
|
||||
If you open that in a browser you should see a `Hello, world!` dialog pop up!
|
||||
If you open https://localhost:8080 in a browser you should see a `Hello, world!`
|
||||
dialog pop up!
|
||||
|
||||
## What just happened?
|
||||
|
||||
|
11
examples/README.md
Normal file
11
examples/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Examples
|
||||
|
||||
This directory contains a number of examples of the `#[wasm_bindgen]` macro and
|
||||
how to display them in the browser. Each directory should contain a `build.sh`
|
||||
which assembles all the relevant files, and then if you open up `index.html` in
|
||||
a web browser you should be able to see everything in action!
|
||||
|
||||
The examples here are:
|
||||
|
||||
* `hello_world` - the "hello world" of `#[wasm_bindgen]`, aka throwing up a
|
||||
dialog greeting you
|
3
examples/hello_world/.gitignore
vendored
Normal file
3
examples/hello_world/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
package-lock.json
|
||||
hello_world.js
|
||||
hello_world_wasm.wasm
|
14
examples/hello_world/Cargo.toml
Normal file
14
examples/hello_world/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "hello_world"
|
||||
version = "0.1.0"
|
||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
# Here we're using a path dependency to use what's already in this repository,
|
||||
# but you'd use the commented out version below if you're copying this into your
|
||||
# project.
|
||||
wasm-bindgen = { path = "../.." }
|
||||
#wasm-bindgen = { git = "https://github.com/alexcrichton/wasm-bindgen" }
|
14
examples/hello_world/README.md
Normal file
14
examples/hello_world/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Hello, World!
|
||||
|
||||
This directory is an example of using the `#[wasm_bindgen]` macro to create an
|
||||
entry point that's called from the browser and then displays a dialog.
|
||||
|
||||
You can build the example with:
|
||||
|
||||
```
|
||||
$ ./build.sh
|
||||
```
|
||||
|
||||
(or running the two commands on Windows manually)
|
||||
|
||||
and then opening up `index.html` in a web browser should show a dialog!
|
15
examples/hello_world/build.sh
Executable file
15
examples/hello_world/build.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
cargo +nightly build --target wasm32-unknown-unknown --release
|
||||
|
||||
# Here we're using the version of the CLI in this repository, but for external
|
||||
# usage you'd use the commented out version below
|
||||
cargo +nightly run --manifest-path ../../crates/wasm-bindgen-cli/Cargo.toml \
|
||||
--bin wasm-bindgen -- \
|
||||
../../target/wasm32-unknown-unknown/release/hello_world.wasm --out-dir .
|
||||
# wasm-bindgen ../../target/wasm32-unknown-unknown/hello_world.wasm --out-dir .
|
||||
|
||||
npm install
|
||||
npm run serve
|
8
examples/hello_world/index.html
Normal file
8
examples/hello_world/index.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
|
||||
</head>
|
||||
<body>
|
||||
<script src='./index.js'></script>
|
||||
</body>
|
||||
</html>
|
5
examples/hello_world/index.js
Normal file
5
examples/hello_world/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
const js = import("./hello_world");
|
||||
|
||||
js.then(js => {
|
||||
js.greet("World!");
|
||||
});
|
10
examples/hello_world/package.json
Normal file
10
examples/hello_world/package.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"scripts": {
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^4.0.1",
|
||||
"webpack-cli": "^2.0.10",
|
||||
"webpack-dev-server": "^3.1.0"
|
||||
}
|
||||
}
|
16
examples/hello_world/src/lib.rs
Normal file
16
examples/hello_world/src/lib.rs
Normal file
@ -0,0 +1,16 @@
|
||||
#![feature(proc_macro)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn alert(s: &str);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[no_mangle]
|
||||
pub extern fn greet(name: &str) {
|
||||
alert(&format!("Hello, {}!", name));
|
||||
}
|
10
examples/hello_world/webpack.config.js
Normal file
10
examples/hello_world/webpack.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: "./index.js",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "index.js",
|
||||
},
|
||||
mode: "development"
|
||||
};
|
Loading…
Reference in New Issue
Block a user