feat(doc): move book over

master
Ashley Williams 7 years ago
parent 87d1b70593
commit bf39e3ed80
  1. 1
      docs/.gitignore
  2. 5
      docs/book.toml
  3. 16
      docs/src/SUMMARY.md
  4. 1
      docs/src/command/pack-and-publish.md
  5. 0
      docs/src/commands/build.md
  6. 1
      docs/src/commands/index.md
  7. 0
      docs/src/commands/init.md
  8. 0
      docs/src/commands/pack-and-publish.md
  9. 0
      docs/src/contributing.md
  10. 0
      docs/src/prerequisites.md
  11. 0
      docs/src/setup.md
  12. 1
      docs/src/tutorial/getting-started.md
  13. 1
      docs/src/tutorial/index.md
  14. 81
      docs/src/tutorial/initialize.md
  15. 17
      docs/src/tutorial/introduction.md
  16. 6
      docs/src/tutorial/next-steps.md
  17. 37
      docs/src/tutorial/packaging-and-publishing.md
  18. 30
      docs/src/tutorial/setup.md
  19. 90
      docs/src/tutorial/using-your-library.md
  20. BIN
      docs/src/tutorial/wasm-pack.png
  21. 137
      docs/src/tutorial/writing-a-libary.md
  22. 1
      docs/src/tutorial/writing-a-rust-webassembly-library.md

1
docs/.gitignore vendored

@ -0,0 +1 @@
book

@ -0,0 +1,5 @@
[book]
authors = ["Ashley Williams"]
multilingual = false
src = "src"
title = "Hello wasm-pack!"

@ -0,0 +1,16 @@
# Summary
- [Prerequisites](./prerequisites.md)
- [Setup](./setup.md)
- [Commands](./commands/index.md)
- [`init`](./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)

@ -0,0 +1,81 @@
# 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!

@ -0,0 +1,17 @@
# 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

@ -0,0 +1,6 @@
# 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!

@ -0,0 +1,37 @@
# Package Code for npm
We've made our code so now we need to package it all up. In your project directory run the following
command:
```bash
$ wasm-pack init --scope MYSCOPE
```
where `MYSCOPE` is your npm username. Normally you could just type `wasm-pack init` but since
other people are doing this tutorial as well we don't want conflicts with the `wasm-add` package
name! This command when run does a few things:
1. It'll compile your code to wasm if you haven't already
2. It'll generate a pkg folder with the wasm file, a JS wrapper file around the wasm, your README,
and a `package.json` file.
This is everything you need to upload your code to npm! Let's do just that!
First off you'll need to login to npm with the account you made earlier if you didn't already have
one:
```bash
$ npm login
```
Next you'll need to go into the `pkg` directory and actually upload the package:
```bash
$ cd pkg
$ npm publish --access=public
```
Now normally if things are not scoped you can just do `npm publish` but if you give it a scope
you'll need to tell npm that this is actually public so it can publish it. We need to do that here
since we gave our packages a scope to avoid conflicting with each other! Next up is actually running
the code and verifying we got it from npm and how we can use that code.

@ -0,0 +1,30 @@
# 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).

@ -0,0 +1,90 @@
# Run The Code From npm
Alright let's make a new small directory to test that we can now run this code and pull it from npm.
```bash
$ mkdir test
$ cd test
```
Now we need to create a `package.json` file that looks like this:
```json
{
"scripts": {
"serve": "webpack-dev-server"
},
"dependencies": {
"@MYSCOPE/wasm-add": "^0.1.0"
},
"devDependencies": {
"webpack": "^4.0.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0"
}
}
```
where `MYSCOPE` is your npm username. You can expand this to be a more complete file but
we're really just trying to verify that this works!
Next up we'll need to create a small webpack configuration so that we can use the
`webpack-dev-server` to serve the wasm file properly. It should be noted that webpack isn't
a requirement. It's just what was chosen for this tutorial. You just need something to server the
code! Here's what your `webpack.config.js` should look like:
```javascript
const path = require('path');
module.exports = {
entry: "./index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.js",
},
mode: "development"
};
```
This tells webpack that if it's going to start things up use `index.js`. Before we do that though
we'll need to setup a small html file. Create a new file called `index.html` and put this inside it:
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>wasm-pack example</title>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
```
We're almost set. Now we need to setup our JS file so that we can run some wasm code!
Make a file called `index.js` and put this inside of it:
```javascript
const js = import("@MYSCOPE/wasm-add/wasm_add.js");
js.then(js => {
js.alert_add(3,2);
});
```
Since web pack [can't load wasm synchronously yet](https://github.com/webpack/webpack/issues/6615)
we are using the import statement above followed
by the promise in order to load it properly. This is what lets us then call `alert_add`. We're
importing from the `node_module` folder we haven't gotten yet so let's import all of our
dependencies finally and run the example!
```bash
$ npm install
$ npm run serve
```
Then in a web browser navigate to `http://localhost:8080` you should see something like this:
![An alert box saying "Hello from Rust! 3 + 2 = 5"](./wasm-pack/wasm-pack.png)
If you did congrats you've successfully uploaded your first bit of wasm code to npm and used it
properly!

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

@ -0,0 +1,137 @@
# 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).

@ -0,0 +1 @@
# Writing a Rust-WebAssembly Library
Loading…
Cancel
Save