Slide 1

Slide 1 text

WebAssembly, Rust y el futuro de JavaScript @lupomontero - LimaJS Dic '18 - Lima, Perú

Slide 2

Slide 2 text

@Laboratoriala @LimaJSorg @NodeSchool @lupomontero @mozillaperu

Slide 3

Slide 3 text

Disclaimer Imágenes, inspiración y algunas ideas a continuación, han sido tomadas de varios recursos abiertos; en particular el blog https://hacks.mozilla.org/ y los posts y presentaciones de Lin Clark (@linclark).

Slide 4

Slide 4 text

Qué es WebAssembly? “WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.” Fuente: https://webassembly.org/

Slide 5

Slide 5 text

Fuente: https://hacks.mozilla.org/2017/02/creating-and-working-with-webassembly-modules/ Licencia: https://creativecommons.org/licenses/by-sa/3.0/

Slide 6

Slide 6 text

Fuente: https://hacks.mozilla.org/2017/02/creating-and-working-with-webassembly-modules/ Licencia: https://creativecommons.org/licenses/by-sa/3.0/

Slide 7

Slide 7 text

Fuente: https://hacks.mozilla.org/2017/02/what-makes-webassembly-fast/ Licencia: https://creativecommons.org/licenses/by-sa/3.0/

Slide 8

Slide 8 text

Fuente: https://hacks.mozilla.org/2017/02/a-cartoon-intro-to-webassembly/ Licencia: https://creativecommons.org/licenses/by-sa/3.0/

Slide 9

Slide 9 text

Fuente: https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/ Licencia: https://creativecommons.org/licenses/by-sa/3.0/

Slide 10

Slide 10 text

Qué es Rust? “Rust es un lenguaje de programación de sistemas extremadamente rápido, previene fallas de segmentación y garantiza la seguridad de los hilos de ejecución.” Fuente: https://www.rust-lang.org/es-ES/

Slide 11

Slide 11 text

● Performance ● Minimal runtime ● Memory safety without GC ● No data races ● High-level abstractions ● Awesome build system / dev experience (rustup, cargo, ...) ● Más amigable para desarrolladorxs web? ● Reemplazo de C y C++? Por qué Rust?

Slide 12

Slide 12 text

Rust vs ... Fuente: “A Case for Oxidation” - Sergio Benítez https://youtu.be/cDFSrVhnZKo?t=262

Slide 13

Slide 13 text

Sin más preámbulo, … nos tiramos a la piscina...

Slide 14

Slide 14 text

Instalar rust curl https://sh.rustup.rs -sSf | sh

Slide 15

Slide 15 text

Rust toolchain y wasm como target ● # configura toolchain nightly por defecto rustup default nightly ● # añade wasm como target rustup target add wasm32-unknown-unknown \ --toolchain nightly Fuente: https://rustwasm.github.io/wasm-bindgen/whirlwind-tour/basic-usage.html

Slide 16

Slide 16 text

Cargo ● cargo new ● cargo init ● cargo run ● cargo build ● cargo test ● cargo install ● cargo publish ● ...

Slide 17

Slide 17 text

Rust => Wasm (101) ● # creamos un proyecto indicando que va a ser una librería cargo new --lib limajs ● Modificamos el tipo de “crate” en Cargo.toml: [lib] crate-type = ["cdylib"]

Slide 18

Slide 18 text

Un poquito de código en Rust! #[no_mangle] pub fn sum(a: i32, b: i32) -> i32 { a + b }

Slide 19

Slide 19 text

Compilemos nuestro programa # Esto debería crear un archivo wasm: # target/wasm32-unknown-unknown/debug/limajs.wasm cargo build --target wasm32-unknown-unknown

Slide 20

Slide 20 text

Invocando una función de Rust desde JavaScript fetch('target/wasm32-unknown-unknown/debug/limajs.wasm') .then(resp => resp.arrayBuffer()) .then(buffer => WebAssembly.instantiate(buffer)) .then(wasm => console.log(wasm.instance.exports.sum(2, 3)));

Slide 21

Slide 21 text

Optimizando el archivo wasm con wasm-gc cargo install wasm-gc # post-procesamos con wasm-gc... wasm-gc \ target/wasm32-unknown-unknown/debug/limajs.wasm \ limajs.gc.wasm

Slide 22

Slide 22 text

Usando wasm optimizado con wasm-gc fetch('limajs.gc.wasm') .then(resp => resp.arrayBuffer()) .then(result => WebAssembly.instantiate(result)) .then(wasm => console.log(wasm.instance.exports.sum(2, 3)));

Slide 23

Slide 23 text

Instanciando wasm haciendo streaming WebAssembly.instantiateStreaming(fetch('limajs.gc.wasm')) .then(mod => console.log(mod.instance.exports.sum(2, 3)))

Slide 24

Slide 24 text

Pasando funciones de JavaScript a Rust Promise WebAssembly.instantiateStreaming(source, options); const options = { env: { printToDOM: msg => document.body.appendChild(document.createTextNode(msg)), }, };

Slide 25

Slide 25 text

Usando funciones de JavaScript en Rust extern { fn printToDOM(x: i32); } #[no_mangle] pub fn run() { unsafe { printToDOM(42); } }

Slide 26

Slide 26 text

Y si necesitamos pasar más que números entre Rust y JavaScript? extern { fn printToDOM(x: String); } #[no_mangle] pub fn run() { unsafe { printToDOM(String::from("OMG")); } }

Slide 27

Slide 27 text

wasm-bindgen ● cargo install wasm-bindgen-cli Fuente: https://rustwasm.github.io/wasm-bindgen/whirlwind-tour/basic-usage.html

Slide 28

Slide 28 text

Cargo.toml [dependencies] wasm-bindgen = "0.2"

Slide 29

Slide 29 text

src/lib.rs extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen(module = "../printToDOM")] extern { fn printToDOM(x: String); } #[wasm_bindgen] pub fn run() { printToDOM(String::from("OMG")); } #[wasm_bindgen] pub fn sum(a: i32, b: i32) -> i32 { a + b }

Slide 30

Slide 30 text

Build y generación de bindings de JavaScript cargo build --target wasm32-unknown-unknown mkdir build wasm-bindgen \ target/wasm32-unknown-unknown/debug/limajs.wasm \ --out-dir ./build

Slide 31

Slide 31 text

Inicializar proyecto de JavaScript yarn init yarn add webpack webpack-cli webpack-dev-server \ html-webpack-plugin

Slide 32

Slide 32 text

Configuración de Webpack const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: './index.js', plugins: [ new HtmlWebpackPlugin({ title: 'Getting started with WASM' }), ], };

Slide 33

Slide 33 text

Usando nuestro módulo desde JavaScript // index.js import('./build/limajs') .then(wasm => wasm.run()) .catch(console.error); https://webpack.js.org/api/module-methods/#import-

Slide 34

Slide 34 text

Arrancando nuestra aplicación... npx webpack-dev-server --mode development ... "scripts": { "start": "webpack-dev-server --mode development" }, ... yarn start

Slide 35

Slide 35 text

Demo time!