feat(book): rework book

master
Ashley Williams 7 years ago
parent bf39e3ed80
commit 4b1e684ffc
  1. 15
      docs/src/SUMMARY.md
  2. 10
      docs/src/commands/index.md
  3. 51
      docs/src/commands/init.md
  4. 4
      docs/src/commands/pack-and-publish.md
  5. 7
      docs/src/getting-started/index.md
  6. 14
      docs/src/getting-started/installation.md
  7. 8
      docs/src/getting-started/project-setup/index.md
  8. 40
      docs/src/getting-started/project-setup/manual-setup.md
  9. 20
      docs/src/getting-started/project-setup/using-a-template.md
  10. 28
      docs/src/prerequisites.md
  11. 6
      docs/src/prerequisites/index.md
  12. 20
      docs/src/prerequisites/npm.md
  13. 31
      docs/src/prerequisites/rust.md
  14. 23
      docs/src/setup.md
  15. 0
      docs/src/tutorial/example-output.png
  16. 1
      docs/src/tutorial/getting-started.md
  17. 11
      docs/src/tutorial/index.md
  18. 81
      docs/src/tutorial/initialize.md
  19. 17
      docs/src/tutorial/introduction.md
  20. 6
      docs/src/tutorial/next-steps.md
  21. 30
      docs/src/tutorial/setup.md
  22. 137
      docs/src/tutorial/writing-a-libary.md

@ -1,16 +1,19 @@
# Summary
- [Prerequisites](./prerequisites.md)
- [Setup](./setup.md)
- [Prerequisites](./prerequisites/index.md)
- [Rust](./prerequisites/rust.md)
- [npm](./prerequisites/npm.md)
- [Getting Started](./getting-started/index.md)
- [Installation](./getting-started/installation.md)
- [Project Setup](./getting-started/project-setup/index.md)
- [Using a Template](./getting-started/project-setup/using-a-template.md)
- [Manual Setup](./getting-started/project-setup/manual-setup.md)
- [Commands](./commands/index.md)
- [`init`](./commands/init.md)
- [`init` (DEPRECATED)](./commands/init.md)
- [`build`](./commands/build.md)
- [`pack` and `publish`](./command/pack-and-publish.md)
- [Tutorial](./tutorial/index.md)
- [Setup](./tutorial/setup.md)
- [Getting Started](./tutorial/getting-started.md)
- [Writing a Rust-WebAssembly Library](./tutorial/writing-a-rust-webassembly-library.md)
- [Packaging and Publishing](./tutorial/packaging-and-publishing.md)
- [Using your Library](./tutorial/using-your-library.md)
- [Next Steps](./tutorial/next-steps.md)
- [Contributing](./contributing.md)

@ -1 +1,11 @@
# Commands
`wasm-pack` has several commands to help you during the process of building
a Rust-generated WebAssembly project.
- `init`: This command has been deprecated in favor of `build`.
- `build`: This command builds a `pkg` directory for you with compiled wasm and generated JS. [Learn more][build]
- `pack` and `publish`: These command will create a tarball, and optionally publish it to a registry, such as npm. [Learn more][pack-pub]
[build]: /commands/build.html
[pack-pub]: /commands/pack-and-publish.html

@ -1,49 +1,6 @@
# wasm-pack init(Deprecated)
# wasm-pack init (DEPRECATED)
The `wasm-pack init` command creates the files neccessary for JavaScript
interoperability and for publishing a package to npm. This involves
generating a pkg folder. This pkg folder will contain the
`README` and a `package.json` file.
This command has been deprecated in favor of `build`, which does the same thing, but is
a much more representative name for the command. [Read the docs for `build`.][build]
## Path
The `wasm-pack init` command can be given an optional path argument, e.g.:
```
wasm-pack init examples/js-hello-world
```
This path should point to a directory that contains a `Cargo.toml` file. If no
path is given, the `init` command will run in the current directory.
## Target
The init command accepts a `--target` argument. This will customize the output files
to align with a particular type of JS module. This allows wasm-pack to generate either
ES6 modules or CommonJS modules for use in browser and in NodeJS. Defaults to `browser`.
The options are:
```
wasm-pack init --target nodejs
```
| Option | Description |
|-----------|-----------------------------------------------------------------------------------------------------------------|
| `nodejs` | Outputs JS that uses CommonJS modules, for use with a `require` statement. |
| `browser` | Outputs JS that uses ES6 modules, primarily for use with `import` statements and/or bundlers such as `webpack`. |
## Scope
The init command also accepts an optional `--scope` argument. This will scope
your package name, which is useful if your package name might conflict with
something in the public registry. For example:
```
wasm-pack init examples/js-hello-world --scope test
```
This command would create a `package.json` file for a package called
`@test/js-hello-world`. For more information about scoping, you can refer to
the npm documentation [here][npm-scope-documentation].
[npm-scope-documentation]: https://docs.npmjs.com/misc/scope
[build]: /commands/build.html

@ -1,4 +1,4 @@
# pack and publish
# pack and publish
The `publish` and `pack` commands interact with the pkg directory that's
created when you run `wasm-pack init`. The `pack` command creates a tarball
@ -29,4 +29,4 @@ $ wasm-pack pack myproject/src/
Unable to find the pkg directory at path 'myproject/src/', or in a child directory of 'myproject/src/'
```
If you don't set a path, they use the current directory as the path.
If you don't set a path, they use the current directory as the path.

@ -0,0 +1,7 @@
# Getting Started
In this section, we'll teach you how to get `wasm-pack` installed and how to setup a project
to use `wasm-pack` with.
- [Installation](/getting-started/installation.html)
- [Project Setup](/getting-started/project-setup/index.html)

@ -0,0 +1,14 @@
## Installation
You can install `wasm-pack` using the following command:
```
cargo install wasm-pack
```
If you have already installed `wasm-pack` and want to install a newer version,
you can use the `--force` option, like this:
```
cargo install wasm-pack --force
```

@ -0,0 +1,8 @@
# Project Setup
There are a few things you need to do to setup a project for `wasm-pack`.
We strongly recommending [using a template], but you can also set the project
up [manually].
[using a template]: /getting-started/project-setup/using-a-template.html
[manually]: /getting-started/project-setup/manual-setup.html

@ -0,0 +1,40 @@
# Manual Setup
You can create a new Rust project named `my-lib` using this command.
```
cargo new --lib my-lib
```
The `--lib` flag specifies that the project is a library, which is important
because we will be calling this code from JavaScript.
#### Cargo.toml changes
You will need to add `wasm-bindgen` to your `Cargo.toml` in the dependencies
section. `wasm-bindgen` is a tool that facilitates interoperability between
wasm modules and JavaScript.
Next, add a `[lib]` section, with a new field named `crate-type` set to
`"cdylib"`. This specifies that the library is a C compatible dynamic library,
which helps `cargo` pass the correct flags to the Rust compiler when targeting
`wasm32`.
After making these changes, your `Cargo.toml` file should look something like
this:
```
[package]
name = "wasm-add"
version = "0.1.0"
authors = ["Michael Gattozzi <mgattozzi@gmail.com>"]
description = "Code used to demonstrate how to use wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/mgattozzi/wasm-add"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen="0.2"
```

@ -0,0 +1,20 @@
# Using a Template
You can create a new Rust-WebAssembly project by using the [rustwasm wasm-pack-template].
To so do, you'll need the `cargo-generate` tool. To install `cargo-generate`:
```
cargo install cargo-generate
```
Then run:
```
cargo generate --git https://github.com/rustwasm/wasm-pack-template
```
You will be prompted to give your project a name. Once you do, you will have a directory
with a new project, ready to go.
[rustwasm wasm-pack-template]: https://github.com/rustwasm/wasm-pack-template

@ -1,29 +1 @@
# Prerequisites
## Rust and npm
Before installing `wasm-pack`, you should make sure that you have already
installed Rust and npm. You can confirm that these are installed using the
following commands:
```sh
# Check if Rust is installed.
cargo --version
# Check if npm is installed.
npm --version
```
You can find more information about installing Rust
[here][rust-wasm-install-info] and more information about installing npm
[here][npm-install-info].
## Sign Up For npm
You will need to create an npm account if you plan on publishing your package to
the npm public registry. You can find information about signing up for npm
[here][npm-signup-info].
[rust-wasm-install-info]: https://rustwasm.github.io/book/setup.html
[npm-install-info]: https://www.npmjs.com/get-npm
[npm-signup-info]: https://www.npmjs.com/signup

@ -0,0 +1,6 @@
# Prerequisites
To run `wasm-pack` you'll need to have both Rust and npm installed and configured.
- [Rust](/prerequisites/rust.html)
- [npm](/prerequisites/npm.html)

@ -0,0 +1,20 @@
# npm
Currently, `wasm-pack` requires that you have npm installed to pack and publish your
package. Longterm, this will be replaced by a Rust only version.
If you would rather use another package manager that interfaces with the npm registry
you may, however, the `pack` and `publish` commands depend on having npm installed.
You can install [npm] by following [these instructions][npm-install-info].
### npm Account
Regardless of which package manager CLI tool you'l like to you, if you wish to publish
your package to the npm registry, or another npm-like registry, you'll need an npm
account.
You can find information about signing up for npm [here][npm-signup-info].
[npm-install-info]: https://www.npmjs.com/get-npm
[npm-signup-info]: https://www.npmjs.com/signup

@ -0,0 +1,31 @@
# Rust
`wasm-pack` is a tool written in Rust, and distributed with `cargo`. As a result,
you'll need Rust and `cargo` to use `wasm-pack`.
To install Rust, visit this [page](https://www.rust-lang.org/en-US/install.html).
You can be sure you have Rust and Cargo installed by running:
```
rustc --version
cargo --version
```
### `nightly` Rust
`wasm-pack` depends on `wasm-bindgen` which currently requires Rust features that
have not yet been stabilized. As a result, you'll need to use a nightly version of
Rust to run `wasm-pack`.
You can install the nightly channel by running:
```
rustup install nightly
```
You can configure rustup to always use `nightly` in a directory by running:
```
rustup override set nightly
```

@ -17,6 +17,27 @@ cargo install wasm-pack --force
## Project Initialization
### Using a Template
You can create a new Rust-WebAssembly project by using the [rustwasm wasm-pack-template].
To so do, you'll need the `cargo-generate` tool. To install `cargo-generate`:
```
cargo install cargo-generate
```
Then run:
```
cargo generate --git https://github.com/rustwasm/wasm-pack-template
```
You will be prompted to give your project a name. Once you do, you will have a directory
with a new project, ready to go.
### Manually
You can create a new Rust project named `my-lib` using this command.
```
@ -26,7 +47,7 @@ cargo new --lib my-lib
The `--lib` flag specifies that the project is a library, which is important
because we will be calling this code from JavaScript.
### Cargo.toml changes
#### Cargo.toml changes
You will need to add `wasm-bindgen` to your `Cargo.toml` in the dependencies
section. `wasm-bindgen` is a tool that facilitates interoperability between

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

@ -1 +1,12 @@
# Tutorial
The goal of this tutorial is to introduce you to the `wasm-pack` workflow.
This tutorial is aimed at folks who are both beginners to WebAssembly and Rust- you don't need
much Rust knowledge to complete this tutorial.
Be sure to have done the following before starting:
1. Read and install all the [Prerequisites](/prerequisites.html).
2. [Install `wasm-pack`](/getting-started/installation.html).
3. [Setup a new project](/getting-started/project-setup/using-a-template.html).

@ -1,81 +0,0 @@
# Project Initialization
Now that we've installed all of our tools and setup our npm account we can actually start coding!
We'll be writing up a small crate that adds two numbers and outputs the numbers. While this will
be a simple example, we're really trying to focus on how to use wasm-pack. You'll be provided links
to other resources so you can make more complicated code to package and ship them to npm!
Let's get started then! First off run this command to create our project:
```bash
$ cargo new --lib wasm-add
```
This will create a new Rust project in a directory called `wasm-add`. We've also specified that
we're building a library, since we'll be calling this code from JS.
Now just:
```bash
$ cd wasm-add
```
You'll find everything in here ready to get started. First though we'll need to add a dependency to
our code and make a few small changes. Open up your `Cargo.toml` file. You should see something like
this inside:
```toml
[package]
name = "wasm-add"
version = "0.1.0"
authors = ["Michael Gattozzi <mgattozzi@gmail.com>"]
[dependencies]
```
This configuration file sets up everything we need to get started but we'll need a few extra fields
and settings to get this to work for wasm and be ready for npm
```toml
[package]
name = "wasm-add"
version = "0.1.0"
authors = ["Michael Gattozzi <mgattozzi@gmail.com>"]
description = "Code used to demonstrate how to use wasm-pack"
license = "MIT/Apache-2.0"
repository = "https://github.com/mgattozzi/wasm-add"
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = "0.2"
```
First off lets look at the last three fields added to the package section `description`, `license`,
and `repository`. npm requires this metadata and so `wasm-pack` won't package your code up until you
have them set. There are more fields that you can add that are more specific to `crates.io` that you
can find [here](https://doc.rust-lang.org/cargo/reference/manifest.html) but for the sake of this
tutorial that's all you need for that section.
You'll also notice we add a new section titled `[lib]`. In here we added this line:
```toml
crate-type = ["cdylib"]
```
Normally Rust compiles the code for the library in a format meant for other Rust packages. We want
our code to work with wasm though! We specify that it's a dynamic library that's C compatible. This
sounds a bit weird but the `wasm32` target will know to interpret this option and instead produce
a wasm binary properly. This is meant to get `cargo` to pass the right parameters to the compiler!
Alright the last thing we added was this to the `[dependencies]` section:
```toml
wasm-bindgen = "0.2"
```
This is the `wasm-bindgen` crate. We'll be using it very shortly to make our functions work nicely
with wasm and not have to worry about a lot of nitty gritty details.
We've got our package's metadata all set up, so let's actually write some code!

@ -1,17 +0,0 @@
# Introduction
`wasm-pack` is a brand new tool designed to make packaging up binaries that include wasm (that may
or may not have JS in them) and make publishing them on npm easy to do. We can't necessarily
distribute Rust code to developers directly and expect them
to build it from scratch. npm is used to install packages for frontend work but it doesn't know how
to compile Rust! With wasm though it's not a problem. Once it's compiled it's all good to go.
However, getting it ready to be distributed, packaging it up properly for npm, and then sending it
to npm can be a bit of a hassle. `wasm-pack` is here to make that easier.
We'll step through creating a simple Rust library, using `wasm-pack` to get it ready for
distribution, sending it to npm, then using it as a package from npm to verify it works!
As with all software in the early stages, this is bleeding edge! Expect some nicks and bruises! If
you run into issues or a bug please file an issue over at it's [repo].
[repo]: https://github.com/rustwasm/wasm-pack/issues

@ -1,6 +0,0 @@
# Next Steps
This was an introduction to wasm-pack but also using wasm code from npm. From here you could
actually improve on the project setup, expand out what your wasm code can actually do, or expand out
how you would use the package you've created. The whole wasm space is completely open so there's no
limit to what you can and can't do really! Go out there and try some cool new things. Happy hacking!

@ -1,30 +0,0 @@
# Tools Setup
## Rust
If you haven't already, you'll need to install nightly Rust with the wasm toolchain!
See [the setup section](setup.html) for more details. Once you've done that you'll need to install
the latest version of `wasm-pack`.
```bash
$ cargo install wasm-pack
```
## npm
If you also have not installed npm already you'll need to do so! Follow the docs available on
[npm](https://www.npmjs.com/get-npm).
To confirm you've succeeded run:
```bash
$ npm --version
```
You should see the version number pop out in your terminal if you installed it successfully!
## npm account
After you have npm installed you'll need to sign up for an account on npm if you have not already
done so in order to complete the tutorial and so you can publish your package. The sign up page can
be found [here](https://www.npmjs.com/signup).

@ -1,137 +0,0 @@
# Rust Code
If you open up `src/lib.rs` you should see a file that looks like this:
```rust
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
```
Let's quickly modify the test suite to work for what we'll be doing. It should look like this:
```rust
#[test]
fn it_works() {
assert_eq!(add(2, 2), 4);
}
```
We'll use this later to make sure our `add` function works!
Now we need to add this to the top of the file:
```rust
#![feature(use_extern_macros, wasm_import_module, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
```
Let's step through this line by line. First up is the list of nightly features. We're enabling this for
the whole crate. What this means is that we will later tag code with an attribute and this will
allow Rust to generate code that we don't have to write by hand. In our case it'll use
`wasm-bindgen.` It should be noted that `#![feature(...)]` implies using the nightly
compiler. This gated feature will hopefully be stabilized and landed soon so that you won't need it!
`wasm-bindgen` knows how to make code that works well with wasm so we don't have to
worry about it too much and just write Rust code for the most part. If you want to know the full
extent of its capabilities check out the README on its repo which can be found
[here](https://github.com/alexcrichton/wasm-bindgen). For our purposes we need to know that if we
want functions to work with wasm easily we'll need it.
The next line says we're importing the `wasm-bindgen` crate and the line after that imports the
prelude from `wasm-bindgen`. The `extern crate` call lets the compiler know what crates to link in
and the `prelude` contains all the types and functions that `wasm-bindgen` needs to work properly!
Cool let's import the `alert` function from JS so that we can call it in our Rust code!
```rust
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
```
Alright so we have our external bit of code and we have everything imported so let's write the
actual `add` function, as well as an `add_alert` function that will use `add` in itself but also
call `alert` to print out the results before returning the value.
```rust
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[wasm_bindgen]
pub fn alert_add(a: i32, b: i32) -> i32 {
let c = add(a, b);
alert(&format!("Hello from Rust! {} + {} = {}", a, b, c));
c
}
```
These functions are fairly straightforward if you're familiar with Rust, but if you're not we'll walk
through it. Both functions take a value `a` and a value `b`. We have said that both are 32 bit
integers (`i32`). We then say both will return an `i32`. The last line in a function returns the value
if there is no semicolon. So in the `add` function the value of `a + b` gets calculated and it's
value is returned! In the case of `alert_add` we store the value of the `add` function we just made
into the variable `c`. We then call `alert` saying what the add operation looked like and what the
value was! We then return what was inside `c`. Neat!
This is all the Rust code we need to write. Your `lib.rs` file should look like this by now:
```rust
#![feature(use_extern_macros, wasm_import_module, wasm_custom_section)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
fn alert(s: &str);
}
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[wasm_bindgen]
pub fn alert_add(a: i32, b: i32) -> i32 {
let c = add(a, b);
alert(&format!("Hello from Rust! {} + {} = {}", a, b, c));
c
}
#[test]
fn it_works() {
assert_eq!(add(2, 2), 4);
}
```
Just to make sure that `add` works we'll run the test we wrote earlier:
```bash
$ cargo test
```
You should get output that looks sort of like this:
```bash
Compiling wasm-add v0.1.1 (file:///home/michael/Code/wasm-add)
Finished dev [unoptimized + debuginfo] target(s) in 0.54 secs
Running target/debug/deps/wasm_add-5d5676e23e39dbea
running 1 test
test it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
```
Yay it all works! Notice we didn't add a test for `alert_add`. This is because Rust won't know what
`alert` is unless the wasm code is running in the browser! Don't worry though. Once we package this
code up and upload it to npm we'll then test out that function to make sure everything works like we
expect it too!
You can find all of the above code [here](https://github.com/mgattozzi/wasm-add).
Loading…
Cancel
Save