Skip to content

Commit

Permalink
Merge pull request #536 from DebugSteven/marketing
Browse files Browse the repository at this point in the history
rust webpack template tutorial
  • Loading branch information
ashleygwilliams authored Feb 22, 2019
2 parents 60f9a0b + 519350f commit d48f4d3
Show file tree
Hide file tree
Showing 9 changed files with 594 additions and 1 deletion.
6 changes: 6 additions & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
- [`pack` and `publish`](./commands/pack-and-publish.md)
- [Tutorials](./tutorials/index.md)
- [Hybrid applications with Webpack](./tutorials/hybrid-applications-with-webpack/index.md)
- [Getting started](./tutorials/hybrid-applications-with-webpack/getting-started.md)
- [Template deep dive](./tutorials/hybrid-applications-with-webpack/template-deep-dive/index.md)
- [`Cargo.toml`](./tutorials/hybrid-applications-with-webpack/template-deep-dive/cargo-toml.md)
- [`src/lib.rs`](./tutorials/hybrid-applications-with-webpack/template-deep-dive/src-lib-rs.md)
- [Building your project](./tutorials/hybrid-applications-with-webpack/template-deep-dive/building-your-project.md)
- [Using your library](./tutorials/hybrid-applications-with-webpack/using-your-library.md)
- [npm browser packages](./tutorials/npm-browser-packages/index.md)
- [Getting started](./tutorials/npm-browser-packages/getting-started.md)
- [Project setup](./tutorials/npm-browser-packages/project-setup/index.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Getting Started

You can create a new Rust-WebAssembly webpack project by using the [rustwasm webpack-template].

Run:

```
npm init rust-webpack my-app
```

The last argument will be your project name. After you run the command, you will have a
directory with a new project, ready to go. We'll talk about what's been included in this
template further in this guide.

[rustwasm webpack-template]: https://github.com/rustwasm/rust-webpack-template
20 changes: 20 additions & 0 deletions docs/src/tutorials/hybrid-applications-with-webpack/index.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
# Hybrid Applications with Webpack

The goal of this tutorial is to introduce you to the `rust-webpack-template`
and the `wasm-pack` workflow by building the example app in the template.

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. [Install `wasm-pack`](../../installer)
1. Read and install the [Prerequisites](../prerequisites/index.html).

- You'll need [Rust], version 1.30 or higher. (Currently either `beta` or `nightly` channels). [Learn more](../project-setup/rust.html).
- You'll need [Node.js] and [npm] installed. [Learn more](../project-setup/npm.html).

⚠️ We strongly recommend that you install [Node.js] using a version manager. You can learn more [here](https://npmjs.com/get-npm).

[Rust]: https://www.rust-lang.org
[Node.js]: https://nodejs.org
[npm]: https://npmjs.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Building your project

We are writing a package that should be used in the browser, so we run this in our terminal:

```bash
$ wasm-pack build
```

If you were writing a package that should be used in Node.js (with CommonJS modules, e.g. `require`),
you would run this in your terminal:

```bash
$ wasm-pack build --target nodejs
```

This command does a few things when run:

1. It'll compile your code to wasm if you haven't already
2. It'll generate a `pkg` folder. Inside there will be:
- a Rust-compiled to wasm file
- a JavaScript wrapper file around the wasm
- TypeScript declaration files to convey information about types
- a `package.json` file
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Cargo.toml

We'll see more about how to use this library when we discuss what has been generated in `lib.rs`.

`Cargo.toml` is the manifest file for Rust's package manager, `cargo`. This file contains
metadata such as name, version, and dependencies for packages, which are call "crates" in Rust.

There's a bunch of metadata that the template gives us, but there are 4 key parts to discuss:

- [`crate-type`](#a1-crate-type)
- [`wasm-bindgen` dependency](#a2-wasm-bindgen-dependency)
- [`[features]` and `wee-alloc`, `console-error-panic-hook` dependencies](#a3-features-and-wee-alloc-console-error-panic-hook-dependencies)
- [`web-sys` dependency](#a4-web-sys-dependency)

<hr/>

## 1. `crate-type`

```toml
[lib]
crate-type = ["cdylib"]
```

A Rust-`wasm` crate is a bit different from a normal crate, and as a result, we need to note
this in our `Cargo.toml`.

When `cargo` is told to build a project, or compilation is otherwise done on a Rust project,
the Rust compiler will need to link crates together, using a particular method, either
statically or dynamically. The two types of crate that you are likely most familiar with are
`#[crate_type = "bin"]` and `#[crate_type = "lib"]`, which are the crate types that largely
represent the difference between Rust application projects and Rust libraries.

`#[crate_type = "cdylib"]` signifies that you'd like the compiler to create a dynamic system
library. This type of library is suited for situations where you'd like to compile Rust code
as a dynamic library to be loaded from another language. In our case, we'll be compiling to a
`*.wasm` file, but this output type will create `*.so` files on Linux, `*.dylib` files on
macOS, and `*.dll` files on Windows in non-`wasm` circumstances.

You can read more about linking and crate types, [here](https://doc.rust-lang.org/reference/linkage.html).

## 2. `wasm-bindgen` dependency

`wasm-bindgen` is our most important dependency. This package allows us to use the
`#[wasm-bindgen]` attribute to tag code that represents the interface we want between
our JavaScript and Rust-generated `wasm`. We can import JS and export Rust by using this
attribute.

```toml
wasm-bindgen = "0.2"
```

We'll see more about how to use this library when we discuss what has been generated in `lib.rs`.

⚠️ If you are coming from JavaScript, you might note that when we add the dependency
there is no `^` or `~` symbol- it looks like we're locking to the `0.2` version.
However, that's not the case! In Rust, the `^` is implied.

## 3. `[features]` and `wee-alloc`, `console-error-panic-hook` dependencies

As part of our effort to design a template that helps people discover useful crates
for their particular use case, this template includes 2 dependencies that can be
very useful for folks developing Rust-`wasm` crates: `console-error-panic-hook` and
`wee-alloc`.

Because these dependencies are useful primarily in a specific portion of the Rust-`wasm`
crate development workflow, we've also set up a bit of glue code that allows us to include
them both as dependences, but allowing for them to be optionally included.

```toml
[features]
default-features = ["console_error_panic_hook"]

[dependencies]
cfg-if = "0.1.5"

# The `console_error_panic_hook` crate provides better debugging of panics by
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1.1", optional = true }

# `wee_alloc` is a tiny allocator for wasm that is only ~1K in code size
# compared to the default allocator's ~10K. It is slower than the default
# allocator, however.
wee_alloc = { version = "0.4.2", optional = true }
```

[`cfg-if`] allows us to check if certain features are enabled on a Rust crate. We'll
use this crate in `lib.rs` to optionally enable `console_error_panic_hook` or
`wee_alloc`. By default, we have `console_error_panic_hook` enabled.
To disable features, we can remove their entry from the `default-features` vector.

To learn more about these features, we discuss them in depth in the `lib.rs` section.

Briefly, they include:

+ **console_error_panic_hook** for logging panic messages to the developer console.
+ **wee_alloc**, an allocator optimized for small code size.

## 4. `web-sys` dependency

The [`web-sys` crate](https://crates.io/crates/web-sys) provides raw wasm-bindgen imports for all of the Web's APIs.
In our `Cargo.toml` file, we list the APIs we want to use from `web-sys` in
order to have them compiled. This crate by default contains very little
when compiled as almost all of its exposed APIs are gated by Cargo features.
Below we see the features that are pulled in by generated Cargo.toml
from the rust-webpack template.

```toml
[dependencies.web-sys]
version = "0.3"
features = [
"Document",
"Element",
"HtmlElement",
"Node",
"Window",
]
```

You can see the exhaustive list of features in `crates/web-sys/Cargo.toml`
and enable them by looking at the [documentation](https://rustwasm.github.io/wasm-bindgen/api/web_sys/)
to see what features they depend on.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Template Deep Dive

⚠️ This section is a deep dive into the contents of the rust-wasm webpack template project,
specifically written for people who are not that familiar with Rust. If you'd rather just
checkout the workflow, feel free to skip this section!

⚠️ If you haven't used a template to set up your project, the contents of your files
may look slightly different than what is described here.

### What the Template Gave Us

Let's start by taking a look at what the template generated for us.

- [`Cargo.toml`](./cargo-toml.html)
- [`src/lib.rs`](./src-lib-rs.html)
Loading

0 comments on commit d48f4d3

Please sign in to comment.