From b71f3374c50ed1534d18f7321689563ef86dfb56 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 21 Feb 2019 11:49:08 -0800 Subject: [PATCH] Tweak introductory and deployment documentation. This commit rejiggers some documentation of `wasm-bindgen` in a few significant ways: * The main landing page now has text and links to the Game of Life tutorial and `wasm-pack`. * The "whirlwind tour" was deleted as it wasn't really serving any purpose that the Game of Life plus the later references weren't already serving. * The "no modules" example was renamed to "without a bundler" * A dedicated section on "Deployment" was added which replaces the previous "No ES Modules" page. This is hopefully more descriptive and also prominently mentions the various options for deployment. --- .travis.yml | 2 +- Cargo.toml | 2 +- examples/no_modules/index.html | 20 -- .../Cargo.toml | 2 +- .../README.md | 4 +- examples/without-a-bundler/index.html | 44 +++++ .../src/lib.rs | 7 +- guide/src/SUMMARY.md | 8 +- guide/src/examples/index.md | 14 +- guide/src/examples/no-modules.md | 20 -- guide/src/examples/without-a-bundler.md | 29 +++ guide/src/introduction.md | 33 ++-- guide/src/reference/deployment.md | 72 +++++++ guide/src/reference/no-esm.md | 79 -------- guide/src/whirlwind-tour/basic-usage.md | 184 ------------------ guide/src/whirlwind-tour/introduction.md | 9 - .../src/whirlwind-tour/what-else-can-we-do.md | 159 --------------- .../src/whirlwind-tour/what-just-happened.md | 33 ---- 18 files changed, 189 insertions(+), 532 deletions(-) delete mode 100644 examples/no_modules/index.html rename examples/{no_modules => without-a-bundler}/Cargo.toml (91%) rename examples/{no_modules => without-a-bundler}/README.md (67%) create mode 100644 examples/without-a-bundler/index.html rename examples/{no_modules => without-a-bundler}/src/lib.rs (84%) delete mode 100644 guide/src/examples/no-modules.md create mode 100644 guide/src/examples/without-a-bundler.md create mode 100644 guide/src/reference/deployment.md delete mode 100644 guide/src/reference/no-esm.md delete mode 100644 guide/src/whirlwind-tour/basic-usage.md delete mode 100644 guide/src/whirlwind-tour/introduction.md delete mode 100644 guide/src/whirlwind-tour/what-else-can-we-do.md delete mode 100644 guide/src/whirlwind-tour/what-just-happened.md diff --git a/.travis.yml b/.travis.yml index 10281e56..ed2b753d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -100,7 +100,7 @@ matrix: - cargo build -p wasm-bindgen-cli - ln -snf target/debug/wasm-bindgen $HOME/.cargo/wasm-bindgen - | - for dir in `ls examples | grep -v README | grep -v asm.js | grep -v raytrace | grep -v no_modules`; do + for dir in `ls examples | grep -v README | grep -v asm.js | grep -v raytrace | grep -v without-a-bundler`; do (cd examples/$dir && ln -fs ../../node_modules . && npm run build -- --output-path $HOME/$TRAVIS_BUILD_NUMBER/exbuild/$dir) || exit 1; diff --git a/Cargo.toml b/Cargo.toml index 9c3b5fc3..381a0daf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,7 +72,6 @@ members = [ "examples/hello_world", "examples/import_js", "examples/julia_set", - "examples/no_modules", "examples/paint", "examples/performance", "examples/raytrace-parallel", @@ -82,6 +81,7 @@ members = [ "examples/wasm2js", "examples/webaudio", "examples/webgl", + "examples/without-a-bundler", "tests/no-std", ] exclude = ['crates/typescript'] diff --git a/examples/no_modules/index.html b/examples/no_modules/index.html deleted file mode 100644 index 4844908e..00000000 --- a/examples/no_modules/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - diff --git a/examples/no_modules/Cargo.toml b/examples/without-a-bundler/Cargo.toml similarity index 91% rename from examples/no_modules/Cargo.toml rename to examples/without-a-bundler/Cargo.toml index 6cd76649..e4f9a451 100644 --- a/examples/no_modules/Cargo.toml +++ b/examples/without-a-bundler/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "no_modules" +name = "without-a-bundler" version = "0.1.0" authors = ["The wasm-bindgen Developers"] edition = "2018" diff --git a/examples/no_modules/README.md b/examples/without-a-bundler/README.md similarity index 67% rename from examples/no_modules/README.md rename to examples/without-a-bundler/README.md index 54f66e9c..e986e752 100644 --- a/examples/no_modules/README.md +++ b/examples/without-a-bundler/README.md @@ -1,8 +1,8 @@ -# Using `--no-modules` +# Without a Bundler [View documentation for this example online][dox] -[dox]: https://rustwasm.github.io/wasm-bindgen/examples/no-modules.html +[dox]: https://rustwasm.github.io/wasm-bindgen/examples/without-a-bundler.html You can build the example locally with: diff --git a/examples/without-a-bundler/index.html b/examples/without-a-bundler/index.html new file mode 100644 index 00000000..1379e8b8 --- /dev/null +++ b/examples/without-a-bundler/index.html @@ -0,0 +1,44 @@ + + + + + + + + + + + diff --git a/examples/no_modules/src/lib.rs b/examples/without-a-bundler/src/lib.rs similarity index 84% rename from examples/no_modules/src/lib.rs rename to examples/without-a-bundler/src/lib.rs index e7388ada..017c6615 100644 --- a/examples/no_modules/src/lib.rs +++ b/examples/without-a-bundler/src/lib.rs @@ -1,6 +1,6 @@ use wasm_bindgen::prelude::*; -// Called by our JS entry point to run the example +// Called when the wasm module is instantiated #[wasm_bindgen(start)] pub fn main() -> Result<(), JsValue> { // Use `web_sys`'s global `window` function to get a handle on the global @@ -17,3 +17,8 @@ pub fn main() -> Result<(), JsValue> { Ok(()) } + +#[wasm_bindgen] +pub fn add(a: u32, b: u32) -> u32 { + a + b +} diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index d05e34d5..7bcaccc6 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -4,15 +4,11 @@ -------------------------------------------------------------------------------- -- [Whirlwind Tour](./whirlwind-tour/introduction.md) - - [Basic Usage](./whirlwind-tour/basic-usage.md) - - [What Just Happened?](./whirlwind-tour/what-just-happened.md) - - [What Else Can We Do?](./whirlwind-tour/what-else-can-we-do.md) - [Examples](./examples/index.md) - [Hello, World!](./examples/hello-world.md) - [Using `console.log`](./examples/console-log.md) - [Small wasm files](./examples/add.md) - - [Using `--no-modules`](./examples/no-modules.md) + - [Without a Bundler](./examples/without-a-bundler.md) - [Converting WebAssembly to JS](./examples/wasm2js.md) - [Importing functions from JS](./examples/import-js.md) - [Working with `char`](./examples/char.md) @@ -30,11 +26,11 @@ - [Parallel Raytracing](./examples/raytrace.md) - [web-sys: A TODO MVC App](./examples/todomvc.md) - [Reference](./reference/index.md) + - [Deployment](./reference/deployment.md) - [Passing Rust Closures to JS](./reference/passing-rust-closures-to-js.md) - [Receiving JS Closures in Rust](./reference/receiving-js-closures-in-rust.md) - [`Promise`s and `Future`s](./reference/js-promises-and-rust-futures.md) - [Iterating over JS Values](./reference/iterating-over-js-values.md) - - [No ES Modules](./reference/no-esm.md) - [Arbitrary Data with Serde](./reference/arbitrary-data-with-serde.md) - [Accessing Properties of Untyped JS Values](./reference/accessing-properties-of-untyped-js-values.md) - [Working with Duck-Typed Interfaces](./reference/working-with-duck-typed-interfaces.md) diff --git a/guide/src/examples/index.md b/guide/src/examples/index.md index 2136e8da..467119f2 100644 --- a/guide/src/examples/index.md +++ b/guide/src/examples/index.md @@ -4,13 +4,19 @@ This subsection contains examples of using the `wasm-bindgen`, `js-sys`, and `web-sys` crates. Each example should have more information about what it's doing. -The source code for all examples can also be [found online][code] to download an -run locally. Most examples are configured with Webpack/`wasm-pack` and can +These examples all assume familiarity with `wasm-bindgen`, `wasm-pack`, and +building a Rust and WebAssembly project. If you're unfamiliar with these check +out the [Game of Life tutorial][gol] to help you get started. + +The source code for all examples can also be [found online][code] to download +and run locally. Most examples are configured with Webpack/`wasm-pack` and can be built with `npm run serve`. Other examples which don't use Webpack are accompanied with a `build.sh` showing how to build it. Note that most examples currently use Webpack to assemble the final output -artifact, but this is not required! You can use the bundler of choice, -`--no-modules`, or native browser ESM support as alternatives to Webpack. +artifact, but this is not required! You can review the [deployment +documentation][deploy] for other options of how to deploy Rust and WebAssembly. [code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples +[gol]: https://rustwasm.github.io/book/ +[deploy]: ../reference/deployment.html diff --git a/guide/src/examples/no-modules.md b/guide/src/examples/no-modules.md deleted file mode 100644 index fae7899d..00000000 --- a/guide/src/examples/no-modules.md +++ /dev/null @@ -1,20 +0,0 @@ -# Using `--no-modules` - -[View full source code][code] - -[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/no_modules - -This example shows how the `--no-modules` flag can be used load code in a -browser directly (using the same code as the [hello world example][hello]). -Most of the magic happens in `index.html`: - -```html -{{#include ../../../examples/no_modules/index.html}} -``` - -And that's it! It's worth pointing out that if [`#[wasm_bindgen(module = -"...")]` imports are used][mod-imp] then `wasm-bindgen --no-modules` will fail -(as it doesn't know how to import modules). - -[hello]: hello-world.html -[mod-imp]: ../reference/attributes/on-js-imports/module.html diff --git a/guide/src/examples/without-a-bundler.md b/guide/src/examples/without-a-bundler.md new file mode 100644 index 00000000..fd88a042 --- /dev/null +++ b/guide/src/examples/without-a-bundler.md @@ -0,0 +1,29 @@ +# Without a Bundler + +[View full source code][code] + +[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/without-a-bundler + +This example shows how the `--no-modules` flag can be used load code in a +browser directly. For this deployment strategy bundlers like Webpack are not +required. For more information on deployment see the [dedicated +documentation](../reference/deployment.html). + +First let's take a look at the code and see how when we're using `--no-modules` +we're not actually losing any functionality! + +```rust +{{#include ../../../examples/without-a-bundler/src/lib.rs}} +``` + +Otherwise the rest of the deployment magic happens in `index.html`: + +```html +{{#include ../../../examples/without-a-bundler/index.html}} +``` + +And that's it! Be sure to read up on the [deployment options] to see what it +means to deploy without a bundler. + +[hello]: hello-world.html +[mod-imp]: ../reference/attributes/on-js-imports/module.html diff --git a/guide/src/introduction.md b/guide/src/introduction.md index 69d91dd8..406575c6 100644 --- a/guide/src/introduction.md +++ b/guide/src/introduction.md @@ -1,15 +1,19 @@ # Introduction -`wasm-bindgen` facilitates high-level interactions between wasm modules and -JavaScript. +This book is about `wasm-bindgen`, a Rust library and CLI tool that facilitate +high-level interactions between wasm modules and JavaScript. The `wasm-bindgen` +tool and crate are only one part of the [Rust and WebAssembly +ecosystem][rustwasm]. If you're not familiar already with `wasm-bindgen` it's +recommended to start by reading the [Game of Life tutorial][gol]. If you're +curious about `wasm-pack`, you can find that [documentation here][wasm-pack]. -This project is sort of half polyfill for features like the [host bindings -proposal][host] and half features for empowering high-level interactions between -JS and wasm-compiled code (currently mostly from Rust). More specifically this -project allows JS/wasm to communicate with strings, JS objects, classes, etc, as -opposed to purely integers and floats. Using `wasm-bindgen` for example you can -define a JS class in Rust or take a string from JS or return one. The -functionality is growing as well! +The `wasm-bindgen` tool is sort of half polyfill for features like the [host +bindings proposal][host] and half features for empowering high-level +interactions between JS and wasm-compiled code (currently mostly from Rust). +More specifically this project allows JS/wasm to communicate with strings, JS +objects, classes, etc, as opposed to purely integers and floats. Using +`wasm-bindgen` for example you can define a JS class in Rust or take a string +from JS or return one. The functionality is growing as well! Currently this tool is Rust-focused but the underlying foundation is language-independent, and it's hoping that over time as this tool stabilizes @@ -22,10 +26,12 @@ Notable features of this project includes: * Exporting Rust functionality to JS such as classes, functions, etc. * Working with rich types like strings, numbers, classes, closures, and objects rather than simply `u32` and floats. +* Automatically generating TypeScript bindings for Rust code being consumed by + JS. -This project is still relatively new but feedback is of course always -welcome! If you're curious about the design plus even more information about -what this crate can do, check out the [design doc]. +With the addition of [`wasm-pack`] you can run the gamut from running Rust on +the web locally, publishing it as part of a larger application, or even +publishing Rust-compiled-to-WebAssembly on NPM! [host]: https://github.com/WebAssembly/host-bindings [design doc]: https://rustwasm.github.io/wasm-bindgen/contributing/design/index.html @@ -33,3 +39,6 @@ what this crate can do, check out the [design doc]. [console-log]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log [perf-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance [hello-online]: https://webassembly.studio/?f=gzubao6tg3 +[rustwasm]: https://rustwasm.github.io/ +[gol]: https://rustwasm.github.io/book/ +[wasm-pack]: https://rustwasm.github.io/wasm-pack/book/ diff --git a/guide/src/reference/deployment.md b/guide/src/reference/deployment.md new file mode 100644 index 00000000..0a59515a --- /dev/null +++ b/guide/src/reference/deployment.md @@ -0,0 +1,72 @@ +# Deploying Rust and WebAssembly + +At this point in time deploying Rust and WebAssembly to the web or other +locations unfortunately isn't a trivial task to do. This page hopes to serve +as documentation for the various known options, and as always PRs are welcome +to update this if it's out of date! + +## Bundlers + +The default output of `wasm-bindgen` assumes a model where the wasm module +itself is natively an ES module. This model, however, not natively implemented +in any JS implementation at this time. As a result, to consume the default +output of `wasm-bindgen` you will need a bundler of some form. + +> **Note**: the choice of this default output was done to reflect the trends of +> the JS ecosystem. While tools other than bundlers don't support wasm files as +> native ES modules today they're all very much likely to in the future! + +Currently the only known bundler known to be fully compatible with +`wasm-bindgen` is [webpack]. Most [examples] use webpack, and you can check out +the [hello world example online] to see the details of webpack configuration +necessary. + +[webpack]: https://webpack.js.org/ +[examples]: ../examples/index.html +[hello world example online]: ../examples/hello-world.html + +## Without a Bundler + +If you're not using a bundler but you're still running code in a web browser, +`wasm-bindgen` still supports this! For this use case you'll want to use the +`--no-modules` flag. You can check out a [full example][nomex] in the +documentation, but the highlights of this output are: + +* When using `wasm-pack` you'll pass `--target no-modules`, and when using + `wasm-bindgen` directly you'll pass `--no-modules`. +* The output can natively be included on a web page, and doesn't require any + further postprocessing. +* The `--no-modules` mode is not able to use NPM dependencies nor local JS + snippets (both currently [proposed][rfc1] [features][rfc2]) +* You'll want to review the [browser requirements] for `wasm-bindgen` because + no polyfills will be available. + +[nomex]: ../examples/without-a-bundler.html +[rfc1]: https://github.com/rustwasm/rfcs/pull/6 +[rfc2]: https://github.com/rustwasm/rfcs/pull/8 +[browser requirements]: browser-support.html + +Despite these limitations almost all code today is compatible with +`--no-modules`, but this area is actively being worked on to improve the +experience so the experience here may be tweaked over time! + +## Node.js + +If you're deploying WebAssembly into Node.js (perhaps as an alternative to a +native module), then you'll want to pass the `--target nodejs` flag to +`wasm-pack` or the `--nodejs` flag to `wasm-bindgen`. + +Like the "without a bundler" strategy, this method of deployment does not +require any further postprocessing. The generated JS shims can be `require`'d +just like any other Node module (even the `*_bg` wasm file can be `require`'d +as it has a JS shim generated as well). + +Note that this method requires a version of Node.js with WebAssembly support, +which is currently Node 8 and above. + +## NPM + +If you'd like to deploy compiled WebAssembly to NPM, then the tool for the job +is [`wasm-pack`]. More information on this coming soon! + +[`wasm-pack`]: https://rustwasm.github.io/wasm-pack/book/ diff --git a/guide/src/reference/no-esm.md b/guide/src/reference/no-esm.md deleted file mode 100644 index 52c923b9..00000000 --- a/guide/src/reference/no-esm.md +++ /dev/null @@ -1,79 +0,0 @@ -# No ES Modules - -Explained a bit more in the [internal design](../contributing/design/index.md) section one of the -key foundational principles of `wasm-bindgen` is ES modules. It supports working -without ES modules, however! Not all JS tooling and browsers are ready for ES -modules by default, so it can sometimes be helpful to quickly get up and running -without them to kick the tires and see how `wasm-bindgen` works. - -Let's start out with our hello-world example from previous chapters, and you can -also [follow along in the repository][repo]. - -[repo]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/no_modules - -```rust -#[wasm_bindgen] -extern "C" { - fn alert(msg: &str); -} - -#[wasm_bindgen] -pub fn greet(name: &str) -> String { - alert(&format!("Hello, {}!", name); -} -``` - -Like usual, we first compile this to wasm: - -``` -$ cargo build --target wasm32-unknown-unknown -``` - -Next, to avoid using ES modules, pass the `--no-modules` option to the -`wasm-bindgen` command: - -``` -$ wasm-bindgen target/wasm32-unknown-unknown/debug/hello.wasm --no-modules --out-dir . -``` - -Next up we need to write some HTML to interact with the wasm: - -```html - - - - - - -``` - -and that's it! If you open up that web page in a browser (needs to be over HTTP) -then you should see an alert for "Hello, World!". - -The `--no-modules` output will not instantiate or compile the wasm module when -included on a web page, instead it just parses and configures the JS bindings -for the wasm-module-to-be. The page is configured with one exported global, in -this case `wasm_bindgen`. The name of this global can be configured with the -`--no-modules-global` option. - -The global `wasm_bindgen` is a function that takes one argument: either the path -to the wasm file to fetch or a `WebAssembly.Module`. When invoked `wasm_bindgen` -will return a promise for when the wasm module is ready-to-go. After that all -exported functionality on `wasm_bindgen` will be functional. - -In the example above, after calling `wasm_bindgen('./hello_bg.wasm')` we wait -for the wasm module to be fetched and compiled, and afterwards we're invoking -our `greet` export. - -Note that exports are available for binding before the wasm module has been -instantiated, for example this would have also worked: - -```js -const { greet } = wasm_bindgen; - -wasm_bindgen('./hello_bg.wasm') - .then(() => greet('World')); -``` diff --git a/guide/src/whirlwind-tour/basic-usage.md b/guide/src/whirlwind-tour/basic-usage.md deleted file mode 100644 index ad38c93a..00000000 --- a/guide/src/whirlwind-tour/basic-usage.md +++ /dev/null @@ -1,184 +0,0 @@ -# Basic Usage - -Let's implement the equivalent of "Hello, world!" for this crate. - -> **Note:** Currently this projects uses *nightly Rust* which you can acquire -> through [rustup] and configure with `rustup default nightly` - -[rustup]: https://rustup.rs - -If you'd like you can dive [straight into an online example][hello-online], but -if you'd prefer to follow along in your own console let's install the tools we -need: - -```shell -$ rustup target add wasm32-unknown-unknown --toolchain nightly -$ cargo +nightly install wasm-bindgen-cli -``` - -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 - -```shell -$ cargo +nightly new js-hello-world --lib -``` - -Now let's add a dependency on this project inside `Cargo.toml` as well as -configuring our build output: - -```toml -[lib] -crate-type = ["cdylib"] - -[dependencies] -wasm-bindgen = "0.2" -``` - -Next up our actual code! We'll write this in `src/lib.rs`: - -```rust,ignore -extern crate wasm_bindgen; -use wasm_bindgen::prelude::*; - -#[wasm_bindgen] -extern "C" { - fn alert(s: &str); -} - -#[wasm_bindgen] -pub fn greet(name: &str) { - alert(&format!("Hello, {}!", name)); -} -``` - -And that's it! If we were to write the `greet` function naively without the -`#[wasm_bindgen]` attribute then JS wouldn't be able to communicate with the -types like `str`, so slapping a `#[wasm_bindgen]` on the function and the import -of `alert` ensures that the right shims are generated. - -Next up let's build our project: - -```shell -$ cargo +nightly build --target wasm32-unknown-unknown -``` - -After this you'll have a wasm file at -`target/wasm32-unknown-unknown/debug/js_hello_world.wasm`. Don't be alarmed at -the size, this is an unoptimized program! - -Now that we've generated the wasm module it's time to run the bindgen tool -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! - -```shell -$ wasm-bindgen target/wasm32-unknown-unknown/debug/js_hello_world.wasm \ - --out-dir . -``` - -This is the main point where the magic happens. The `js_hello_world.wasm` file -emitted by rustc contains *descriptors* of how to communicate via richer types -than wasm currently supports. The `wasm-bindgen` tool will interpret this -information, emitting a **replacement module** for the wasm file. - -The previous `js_hello_world.wasm` file is interpreted as if it were an ES6 -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 few other files needed to implement this -module. For example `js_hello_world_bg.wasm` is the original wasm file but -postprocessed a bit. It's intended that the `js_hello_world_bg.wasm` file, -like before, acts like an ES6 module. - -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 Webpack's 4.0 beta release has native wasm -support! Let's take a look at that and see how it works. - -First, create an `index.js` file: - -```js -const js = import("./js_hello_world"); - -js.then(js => { - js.greet("World!"); -}); -``` - -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, define our JS dependencies by creating a `package.json`: - -```json -{ - "scripts": { - "serve": "webpack-dev-server" - }, - "devDependencies": { - "html-webpack-plugin": "^3.2.0", - "webpack": "^4.0.1", - "webpack-cli": "^3.1.1", - "webpack-dev-server": "^3.1.0" - } -} -``` - -and our `webpack` configuration: - -```js -// webpack.config.js -const path = require('path'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); - -module.exports = { - entry: "./index.js", - output: { - path: path.resolve(__dirname, "dist"), - filename: "index.js", - }, - plugins: [ - new HtmlWebpackPlugin({ - title: "Getting started with WASM" - }) - ], - mode: "development" -}; -``` - -And finally: - -```shell -$ npm install -$ npm run serve -``` - -If you open [http://localhost:8080](http://localhost:8080) in a browser you should see a `Hello, world!` -dialog pop up! - -Notice that `html-webpack-plugin` has generated an HTML page which includes `index.js`. - -Finally, you may want to deploy your application to a web server like Apache or NGINX. -For that, simply run: - -```shell -$ npx webpack -``` - -The output will be in the `dist` directory. You can now copy it to the root of your -web server. - -If that was all a bit much, no worries! You can [execute this code -online][hello-online] thanks to [WebAssembly Studio](https://webassembly.studio) -or you can [follow along on GitHub][hello-tree] to see all the files necessary -as well as a script to set it all up. - -[hello-tree]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world -[hello-readme]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world/README.md -[hello-online]: https://webassembly.studio/?f=gzubao6tg3 diff --git a/guide/src/whirlwind-tour/introduction.md b/guide/src/whirlwind-tour/introduction.md deleted file mode 100644 index 10ac8a7c..00000000 --- a/guide/src/whirlwind-tour/introduction.md +++ /dev/null @@ -1,9 +0,0 @@ -# A Whirlwind Tour of `wasm-bindgen` - -What follows is a whirlwind tour of `wasm-bindgen`. - -You will learn: - -* Setting up your development environment for `wasm-bindgen` -* Importing JavaScript functions and classes into Rust -* Exporting Rust structs and functions to JavaScript diff --git a/guide/src/whirlwind-tour/what-else-can-we-do.md b/guide/src/whirlwind-tour/what-else-can-we-do.md deleted file mode 100644 index 0b465a4a..00000000 --- a/guide/src/whirlwind-tour/what-else-can-we-do.md +++ /dev/null @@ -1,159 +0,0 @@ -# What Else Can We Do? - -Much more! Here's a taste of various features you can use in this project. You -can also [explore this code online](https://webassembly.studio/?f=t61j18noqz): - -```rust,ignore -// src/lib.rs -extern crate wasm_bindgen; - -use wasm_bindgen::prelude::*; - -// Strings can both be passed in and received -#[wasm_bindgen] -pub fn concat(a: &str, b: &str) -> String { - let mut a = a.to_string(); - a.push_str(b); - return a -} - -// A struct will show up as a class on the JS side of things -#[wasm_bindgen] -pub struct Foo { - contents: u32, -} - -#[wasm_bindgen] -impl Foo { - #[wasm_bindgen(constructor)] - pub fn new() -> Foo { - Foo { contents: 0 } - } - - // Methods can be defined with `&mut self` or `&self`, and arguments you - // can pass to a normal free function also all work in methods. - pub fn add(&mut self, amt: u32) -> u32 { - self.contents += amt; - return self.contents - } - - // You can also take a limited set of references to other types as well. - pub fn add_other(&mut self, bar: &Bar) { - self.contents += bar.contents; - } - - // Ownership can work too! - pub fn consume_other(&mut self, bar: Bar) { - self.contents += bar.contents; - } -} - -#[wasm_bindgen] -pub struct Bar { - contents: u32, - opaque: JsValue, // defined in `wasm_bindgen`, imported via prelude -} - -#[wasm_bindgen(module = "./index")] // what ES6 module to import from -extern "C" { - fn bar_on_reset(to: &str, opaque: &JsValue); - - // We can import classes and annotate functionality on those classes as well - type Awesome; - #[wasm_bindgen(constructor)] - fn new() -> Awesome; - #[wasm_bindgen(method)] - fn get_internal(this: &Awesome) -> u32; - // We can call javascript functions that have a dynamic number of arguments, - // e.g. rust `sum(&[1, 2, 3])` will be called like `sum(1, 2, 3)` - #[wasm_bindgen(variadic)] - fn sum(vals: &[u32]) -> u32; -} - -#[wasm_bindgen] -impl Bar { - pub fn from_str(s: &str, opaque: JsValue) -> Bar { - let contents = s.parse().unwrap_or_else(|_| { - Awesome::new().get_internal() - }); - Bar { contents, opaque } - } - - pub fn reset(&mut self, s: &str) { - if let Ok(n) = s.parse() { - bar_on_reset(s, &self.opaque); - self.contents = n; - } - } -} -``` - -The generated JS bindings for this invocation of the macro [look like -this][bindings]. You can view them in action like so: - -[bindings]: https://gist.github.com/alexcrichton/3d85c505e785fb8ff32e2c1cf9618367 - -and our corresponding `index.js`: - -```js -import { Foo, Bar, concat } from "./js_hello_world"; -import { booted } from "./js_hello_world_wasm"; - -export function bar_on_reset(s, token) { - console.log(token); - console.log(`this instance of bar was reset to ${s}`); -} - -function assertEq(a, b) { - if (a !== b) - throw new Error(`${a} != ${b}`); - console.log(`found ${a} === ${b}`); -} - -function main() { - assertEq(concat('a', 'b'), 'ab'); - - // Note that to use `new Foo()` the constructor function must be annotated - // with `#[wasm_bindgen(constructor)]`, otherwise only `Foo.new()` can be used. - // Additionally objects allocated corresponding to Rust structs will need to - // be deallocated on the Rust side of things with an explicit call to `free`. - let foo = new Foo(); - assertEq(foo.add(10), 10); - foo.free(); - - // Pass objects to one another - let foo1 = new Foo(); - let bar = Bar.from_str("22", { opaque: 'object' }); - foo1.add_other(bar); - - // We also don't have to `free` the `bar` variable as this function is - // transferring ownership to `foo1` - bar.reset('34'); - foo1.consume_other(bar); - - assertEq(foo1.add(2), 22 + 34 + 2); - foo1.free(); - - alert('all passed!') -} - -export class Awesome { - constructor() { - this.internal = 32; - } - - get_internal() { - return this.internal; - } -} - -export function sum(...args) { - let answer = 0; - for(var i=0; i