|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +title: "Reflecting on Rust and WebAssembly in 2018" |
| 4 | +--- |
| 5 | + |
| 6 | +[**🎉 The 2018 edition of Rust has officially shipped, and the initial Rust and |
| 7 | +WebAssembly development story along with it! 🎉**][rust-2018] |
| 8 | + |
| 9 | +To see how far we've come, let's reflect on the Rust and WebAssembly story a |
| 10 | +year ago: `rustc` could emit WebAssembly binaries for you, but that was about |
| 11 | +it. As far as communication with JavaScript went, you had to work with raw wasm |
| 12 | +imports and exports yourself. That meant you could only pass 32- and 64-bit |
| 13 | +integers and floats back and forth. No Rust structs, JavaScript objects, |
| 14 | +strings, or slices could be passed back forth. And distributing your library's |
| 15 | +`.wasm` so that other downstream projects could depend on it? Good luck. |
| 16 | + |
| 17 | +While it was [clear there was huge potential for Rust and |
| 18 | +WebAssembly][case-for-rust-wasm-2018], no one was sure what exactly that |
| 19 | +meant. So when the Rust and WebAssembly domain working group formed, we rallied |
| 20 | +around making this shared vision into a reality: |
| 21 | + |
| 22 | +> #### Compiling Rust to WebAssembly should be the best choice for fast, reliable code for the Web. |
| 23 | +
|
| 24 | +As our ideas evolved, we distilled another core value: |
| 25 | + |
| 26 | +> #### Rust and WebAssembly is here to *augment* your JavaScript, not replace it. |
| 27 | +
|
| 28 | +The same way that Rust integrates with C libraries and calling conventions on |
| 29 | +native targets, it should play nice with JavaScript and HTML5 APIs on the |
| 30 | +Web. You should *not* have to rewrite your whole Web application or JavaScript |
| 31 | +library. We cannot realize our vision for Rust and wasm if it means you have to |
| 32 | +start over from scratch; it wouldn't be practical. |
| 33 | + |
| 34 | +Given these shared values and vision, we set out goals for what we wanted the |
| 35 | +Rust and WebAssembly ecosystem, toolchain, and workflow to look like by the time |
| 36 | +Rust 2018 shipped. |
| 37 | + |
| 38 | +### Goal: ☑ Zero-Cost JavaScript Interoperation |
| 39 | + |
| 40 | +Rust enables fast *and* expressive code by leveraging zero-cost abstractions. We |
| 41 | +wanted to apply this principal to our whole JS interop infrastructure. Yes, you |
| 42 | +can write your own boilerplate to pass DOM nodes to Rust-generated wasm, but you |
| 43 | +shouldn't have to, and the provided infrastructure should be as fast as if you |
| 44 | +*did* hand-code it. If you call IndexedDB APIs, that shouldn't bloat your |
| 45 | +`.wasm` binary with unused bindings to Web GL functions. |
| 46 | + |
| 47 | +[We created `wasm-bindgen` as the foundation for zero-cost JavaScript |
| 48 | +interoperation.][wasm-bindgen] `wasm-bindgen` facillitates communication between |
| 49 | +JavaScript and WebAssembly, and generates glue code that you would otherwise |
| 50 | +have to write yourself. On top of `wasm-bindgen`, [we built `js-sys` (raw |
| 51 | +bindings to ECMAScript APIs) and `web-sys` (raw bindings to Web |
| 52 | +APIs)][announcing-web-sys]. |
| 53 | + |
| 54 | +Using the `wasm-bindgen` ecosystem, we can easily and performantly |
| 55 | + |
| 56 | +* export rich APIs from our Rust-generated wasm libraries, so they are callable |
| 57 | + from JavaScript, and |
| 58 | +* import JavaScript and Web APIs into our Rust-generated wasm. |
| 59 | + |
| 60 | +All in a zero-cost manner. |
| 61 | + |
| 62 | +Additionally, `wasm-bindgen` is forward-compatible with the [WebAssembly host |
| 63 | +bindings proposal][host-bindings]. Host bindings will remove the tiny, generated |
| 64 | +JavaScript shim functions that sit between our wasm functions and DOM |
| 65 | +methods. Eventually, host bindings promises to unlock |
| 66 | +even-faster-than-JavaScript DOM access since calls can be statically validated |
| 67 | +once rather than dynamically checked every time. |
| 68 | + |
| 69 | +### Goal: ☑ Distributing Rust-Generated Wasm as an NPM Library |
| 70 | + |
| 71 | +Superb integration isn't only about exporting and importing functionality |
| 72 | +between Rust-generated WebAssembly and JavaScript. It is also fitting into the |
| 73 | +JavaScript's distribution mechanisms, and a big chunk of that story is |
| 74 | +[NPM][]. |
| 75 | + |
| 76 | +We [built `wasm-pack`][wasm-pack] to make it easy to create and publish NPM |
| 77 | +packages from your Rust and WebAssembly code. There didn't used to be any story |
| 78 | +whatsoever for sharing Rust-generated wasm modules. Now, all it takes is: |
| 79 | + |
| 80 | +``` |
| 81 | +wasm-pack publish |
| 82 | +``` |
| 83 | + |
| 84 | +### Goal: ☑ Get Developers Productive Fast |
| 85 | + |
| 86 | +We wrote [a Rust and WebAssembly book][book] that teaches you all the ins and |
| 87 | +outs of WebAssembly development with Rust. It features [a tutorial where you |
| 88 | +build an implementation of Conway's Game of Life][tutorial], and then you learn |
| 89 | +to write tests for headless browsers, debug wasm code when things go wrong, and |
| 90 | +how to diagnose slow code paths and then speed them up. |
| 91 | + |
| 92 | +We realized that there are a bunch of "post-build" tools you want to run after |
| 93 | +`cargo` and `rustc` emit the initial `.wasm` binary. For usability and developer |
| 94 | +productivity, we expanded `wasm-pack`'s role from creating and publishing NPM |
| 95 | +packages to orchestrating all of these tasks. `wasm-pack` will manage your |
| 96 | +`wasm-bindgen` CLI binaries and install browsers' WebDriver clients for you |
| 97 | +automatically. |
| 98 | + |
| 99 | +For example, want to run tests in a headless Firefox browser? Just run |
| 100 | + |
| 101 | +``` |
| 102 | +wasm-pack test --headless --firefox |
| 103 | +``` |
| 104 | + |
| 105 | +No need to pull your hair out trying to install and configure anything! |
| 106 | + |
| 107 | +Finally, we recognized that getting your Rust and WebAssembly project set up |
| 108 | +initially involves a bit of boilerplate and configuration that new users aren't |
| 109 | +prepared for and experienced users don't want to waste time on. So we created a |
| 110 | +variety of project templates for different use cases, so you can hit the ground |
| 111 | +running: |
| 112 | + |
| 113 | +* [`wasm-pack-template`][wasm-pack-template] for creating NPM libraries with |
| 114 | + Rust and Wasm. |
| 115 | +* [`create-wasm-app`][create-wasm-app] for creating Web applications built on |
| 116 | + top of Rust-generated wasm NPM libraries. |
| 117 | +* [`rust-webpack-template`][rust-webpack-template] for creating whole Web |
| 118 | + applications with Rust, WebAssembly, and the Webpack bundler. |
| 119 | +* [`rust-parcel-template`][rust-parcel-template] for creating whole Web |
| 120 | + applications with Rust, WebAssembly, and the Parcel bundler. |
| 121 | + |
| 122 | +### Goal: ☑ Rust-Generated Wasm Should be Testable and Debuggable |
| 123 | + |
| 124 | +We recognized that testing and debugging infrastructure are table stakes for |
| 125 | +creating reliable code and developer productivity. |
| 126 | + |
| 127 | +By default, wasm can't log any panics or errors because it doesn't have any |
| 128 | +"syscall" or I/O functionality. You have to add imports for that sort of thing |
| 129 | +yourself, and then instantiate the module with the appropriate functions. To |
| 130 | +remedy this problem, and to ensure that panics are always debuggable, we created |
| 131 | +[the `console_error_panic_hook` crate][console_error_panic_hook], which |
| 132 | +redirects panic messages into the browser's devtools console. |
| 133 | + |
| 134 | +While you can always run normal `#[test]`s on the native target for portable, |
| 135 | +platform-agnostic code, that isn't sufficient for testing your library's |
| 136 | +interaction with the DOM, asynchronous JavaScript promises, or event |
| 137 | +handlers. So we created [the `wasm-bindgen-test` |
| 138 | +infrastructure][wasm-bindgen-test], and made installing and configuring the |
| 139 | +necessary binaries for headless browser and Node.js testing a breeze with |
| 140 | +`wasm-pack test`. |
| 141 | + |
| 142 | +We also had experienced that diagnosing where code size was coming from could be |
| 143 | +hard with WebAssembly. We wanted to know things like which function was calling |
| 144 | +another function, and causing it to be included in the `.wasm` binary, so we |
| 145 | +created [the Twiggy🌱 code size profiler for WebAssembly][twiggy]. |
| 146 | + |
| 147 | +``` |
| 148 | + Shallow Bytes │ Shallow % │ Retaining Paths |
| 149 | +───────────────┼───────────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── |
| 150 | + 152 ┊ 5.40% ┊ wee_alloc::alloc_with_refill::hb32c1bbce9ebda8e |
| 151 | + ┊ ┊ ⬑ func[2] |
| 152 | + ┊ ┊ ⬑ <wee_alloc::size_classes::SizeClassAllocPolicy<'a> as wee_alloc::AllocPolicy>::new_cell_for_free_list::h3987e3054b8224e6 |
| 153 | + ┊ ┊ ⬑ func[5] |
| 154 | + ┊ ┊ ⬑ elem[0] |
| 155 | + ┊ ┊ ⬑ hello |
| 156 | + ┊ ┊ ⬑ func[8] |
| 157 | + ┊ ┊ ⬑ export "hello" |
| 158 | +``` |
| 159 | + |
| 160 | +## #RustWasm2019 |
| 161 | + |
| 162 | +All of our goals have been focused on things we could deliver in tandem with the |
| 163 | +2018 edition. But now that the 2018 edition has shipped, it is time to think |
| 164 | +about what we want to achieve in 2019 and beyond. |
| 165 | + |
| 166 | +**This is where you come in!** |
| 167 | + |
| 168 | +Following in the larger Rust project's [tradition][rust-2019-call-for-blogs], |
| 169 | +we're asking the community to write blog posts reflecting on Rust and |
| 170 | +WebAssembly in 2018 and proposing goals and directions for Rust and WebAssembly |
| 171 | +in 2019. We'll read everything, and then propose an [RFC][rust-wasm-rfcs] for |
| 172 | +the Rust and WebAssembly domain working group's roadmap in 2019. |
| 173 | + |
| 174 | +Write down your thoughts on whatever your writing platform of choice is. It |
| 175 | +could be: |
| 176 | + |
| 177 | +* Your personal or company blog |
| 178 | +* A GitHub gist |
| 179 | +* A Medium post |
| 180 | +* Any other platform you prefer |
| 181 | + |
| 182 | +We're looking for posts on many different topics: |
| 183 | + |
| 184 | +* Ideas for community programs |
| 185 | +* Tooling enhancements |
| 186 | +* Ecosystem and library needs |
| 187 | +* Documentation improvements |
| 188 | +* Anything else related to Rust and Wasm! |
| 189 | + |
| 190 | +Tweet your write up with [the `#RustWasm2019` hashtag][hashtag] or drop a link |
| 191 | +on [this github issue][rust-wasm-2019-issue]. We'll aggregate everything |
| 192 | +everyone has written in another big post on this blog. Then, the core Rust and |
| 193 | +WebAssembly working group team will read over all of them and write up an RFC |
| 194 | +for the working group's 2019 roadmap! This RFC will follow our normal [RFC |
| 195 | +process][] and everyone will have a chance to discuss it, improve it, and help |
| 196 | +polish it. |
| 197 | + |
| 198 | +## Preliminary Timeline |
| 199 | + |
| 200 | +* **Now through January 15<sup>th</sup>:** Share your `#RustWasm2019` post, read |
| 201 | + posts by others, discuss them, bounce ideas back and forth. |
| 202 | +* **End of January:** We'll formally propose the 2019 roadmap RFC, and then work |
| 203 | + it through the RFC process together as a community. |
| 204 | +* **End of February:** We're aiming for having consensus on the 2019 roadmap and |
| 205 | + merging the RFC before the end of February. |
| 206 | + |
| 207 | +## Thank You for a Wonderful 2018! 💖 |
| 208 | + |
| 209 | +Thanks to everyone who contributed to Rust and WebAssembly in 2018! Here's to an |
| 210 | +equally awesome and exciting 2019! |
| 211 | + |
| 212 | +[rust-2018]: TODO |
| 213 | +[case-for-rust-wasm-2018]: https://mgattozzi.com/rust-wasm/ |
| 214 | +[rust-2019-call-for-blogs]: TODO https://github.com/rust-lang/blog.rust-lang.org/pull/292 |
| 215 | +[rust-wasm-rfcs]: https://github.com/rustwasm/rfcs |
| 216 | +[hashtag]: https://twitter.com/search?q=%23RustWasm2019 |
| 217 | +[rust-wasm-2019-issue]: TODO |
| 218 | +[RFC process]: https://rustwasm.github.io/rfcs/001-the-rfc-process.html |
| 219 | +[Bjarne Stroustrup]: https://en.wikipedia.org/wiki/Bjarne_Stroustrup |
| 220 | +[announcing-web-sys]: https://rustwasm.github.io/2018/09/26/announcing-web-sys.html |
| 221 | +[wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen |
| 222 | +[host-bindings]: https://github.com/WebAssembly/host-bindings/blob/master/proposals/host-bindings/Overview.md |
| 223 | +[NPM]: https://www.npmjs.com/ |
| 224 | +[wasm-pack]: https://github.com/rustwasm/wasm-pack |
| 225 | +[book]: https://rustwasm.github.io/book/ |
| 226 | +[tutorial]: https://rustwasm.github.io/book/game-of-life/introduction.html |
| 227 | +[wasm-pack-template]: https://github.com/rustwasm/wasm-pack-template |
| 228 | +[create-wasm-app]: https://github.com/rustwasm/create-wasm-app |
| 229 | +[rust-webpack-template]: https://github.com/rustwasm/rust-webpack-template |
| 230 | +[rust-parcel-template]: https://github.com/rustwasm/rust-parcel-template |
| 231 | +[console_error_panic_hook]: https://github.com/rustwasm/console_error_panic_hook |
| 232 | +[wasm-bindgen-test]: https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/index.html |
| 233 | +[twiggy]: https://github.com/rustwasm/twiggy |
0 commit comments