Primer za WebAssembly: započnite s WebAssembly

WebAssembly obećava potpuno novu vrstu weba - brže performanse za korisnike i veću fleksibilnost za programere. Umjesto da bude zaključan da koristi JavaScript kao jedini jezik za klijentsku web-interakciju, programer može birati između širokog spektra drugih jezika - C, TypeScript, Rust, Ruby, Python - i raditi na onom kojem je najprikladniji s.

Izvorno, jedini način za stvaranje WebAssembly (ili skraćeno WASM) bio je kompajliranje C / C ++ koda u WebAssembly pomoću alata Emscripten. Danas programeri ne samo da imaju više jezičnih opcija, već je postalo lakše kompajlirati ove druge jezike izravno u WebAssembly, s manje interventnih koraka.

U ovom ćemo dijelu ispitati korake potrebne za implementaciju komponenata WebAssembly u web aplikaciju. Budući da je WebAssembly u tijeku, koraci uvelike ovise o tome koji jezik koristite, a lanac alata vjerojatno će se mijenjati neko vrijeme. Ali trenutno je moguće pisati i implementirati korisne, ali minimalne programe WebAssembly na više jezika.

Odaberite jezik koji podržava WebAssembly

Prvi korak prema postavljanju aplikacije WebAssembly je odabir jezika koji se može kompajlirati u WebAssembly kao cilj. Postoji velika vjerojatnost da se barem jedan od glavnih jezika koje koristite u proizvodnji može pretvoriti u WebAssembly ili ima kompajler koji može emitirati WebAssembly.

Evo vodećih:

  • C. Očito. Tipičan način za pretvaranje C koda u WebAssembly je putem Emscriptena, jer je C-to-Emscripten-to-WebAssembly bio prvi alatni lanac WebAssembly koji se pojavio. Ali pojavljuju se drugi alati. Čitav kompajler, Cheerp, dizajniran je posebno za generiranje aplikacija WebAssembly iz C / C ++ koda. Cheerp također može ciljati JavaScript, asm.js ili bilo koju kombinaciju gore navedenog. Također je moguće koristiti Clang lanac alata za izgradnju korisnog tereta WebAssembly, iako postupak još uvijek zahtijeva dosta ručnog podizanja. (Evo jednog primjera.)
  • Rđa. Mozillin sistemski programski jezik, dizajniran da bude siguran i brz, jedan je od glavnih kandidata za matičnu podršku za WebAssembly. Proširenja na lancu alata Rust omogućuju vam kompajliranje izravno s Rust koda na WebAssembly. Morate koristiti Rustov nightlylanac alata za obavljanje WebAssembly kompilacije, tako da bi ovu značajku za sada trebalo smatrati eksperimentalnom.
  • TypeScript . Prema zadanim postavkama TypeScript se kompajlira u JavaScript, što znači da bi se zauzvrat mogao kompajlirati u WebAssembly. Projekt AssemblyScript smanjuje broj uključenih koraka, omogućujući da se strogo upisani TypeScript kompajlira u WebAssembly.

Nekoliko drugih jezika počinje ciljati WebAssembly, ali oni su u vrlo ranoj fazi. Sljedeći se jezici mogu koristiti za izradu komponenata WebAssembly, ali samo na ograničenije načine od C, Rust i TypeScript:

  • D . Jezik D nedavno je dodao podršku za sastavljanje i povezivanje izravno na WebAssembly.
  • Java . Java bytecode može se unaprijed prevesti u WebAssembly putem projekta TeaVM. To znači da se bilo koji jezik koji emitira Java bajt kod može kompajlirati u WebAssembly - na primjer, Kotlin, Scala ili Clojure. Međutim, mnogi Java API-ji koji se ne mogu učinkovito implementirati u WebAssembly su ograničeni, poput API-ja za refleksiju i resurse, pa je TeaVM - a time i WebAssembly - korisna samo za podskup aplikacija temeljenih na JVM-u. 
  • Lua . Jezik skripti Lua ima dugu povijest upotrebe kao ugrađeni jezik, baš kao i JavaScript. Međutim, jedini projekti koji pretvaraju Lua u WebAssembly uključuju upotrebu mehanizma za izvršavanje u pregledniku: wasm_lua ugrađuje Lua runtime u preglednik, dok Luwa JIT kompajlira Lua u WebAssembly.
  • Kotlin / Zavičajni . Ljubitelji jezika Kotlin, izdvajanja Java, s nestrpljenjem su iščekivali potpuno izdanje Kotlina / Native, LLVM pozadine za prevodilac Kotlin koji može proizvesti samostalne binarne datoteke. Kotlin / Native 0.4 uveo je podršku za WebAssembly kao cilj kompilacije, ali samo kao dokaz koncepta.
  • .Net . Jezici .Net još nemaju potpunu podršku WebAssembly, ali neki su eksperimenti započeli. Pogledajte Blazor, koji se može koristiti za izradu web stranica s jednom stranicom u .Netu putem C # i Microsoftove sintakse "Razor".
  • Nim . Ovaj se nadolazeći jezik kompajlira u C, tako da bi se u teoriji mogao kompilirati rezultirajući C u WebAssembly. Međutim, eksperimentalni back end za Nim nazvan nwasm je u fazi izrade.
  • Ostali jezici koji pokreću LLVM . U teoriji, bilo koji jezik koji koristi okvir kompajlera LLVM može se kompajlirati u WebAssembly, jer LLVM podržava WebAssembly kao jedno od mnogih ciljeva. Međutim, to ne znači nužno da će se bilo koji jezik kompiliran za LLVM izvoditi onakav kakav jest u WebAssemblyu. To samo znači da LLVM olakšava ciljanje WebAssemblya.

Svi gore navedeni projekti pretvaraju izvorni program ili generirani bytecode u WebAssembly. Ali za interpretirane jezike kao što su Ruby ili Python, postoji još jedan pristup: Umjesto pretvaranja samih aplikacija, izvršavanje jezika pretvara se  u WebAssembly. Programi se tada izvode takvi kakvi jesu na pretvorenom vremenu izvođenja. Budući da su mnoga izvođenja jezika (uključujući Ruby i Python) napisana na C / C ++, postupak pretvorbe u osnovi je isti kao i kod bilo koje druge aplikacije C / C ++.

To naravno znači da pretvoreno vrijeme izvođenja mora biti preuzeto u preglednik prije nego što se bilo koji program može pokrenuti s njim, usporavajući učitavanje i vremena raščlanjivanja. "Čista" verzija aplikacije WebAssembly jednostavnija je. Stoga je runtime pretvorba u najboljem slučaju mjera zaustavljanja sve dok više jezika ne podržava WebAssembly kao cilj izvoza ili kompilacije.

Integrirajte WebAssembly s JavaScriptom

Sljedeći je korak pisanje koda na jeziku koji ste odabrali, uz malo pažnje kako će taj kôd komunicirati s okolinom WebAssembly, zatim ga kompajlirati u modul WebAssembly (binarni WASM) i na kraju integrirati taj modul s postojećim JavaScript aplikacija.

Točni koraci za izvoz koda u WebAssembly uvelike će se razlikovati ovisno o lancu alata. Oni će također ponešto odstupiti od načina na koji se grade redoviti izvorni binarni programi za taj jezik. Na primjer, u Rustu ćete morati slijediti nekoliko koraka:

  1. Postavite nightly izradu za Rust s wasm32-unknown-unknownlancem alata.
  2. Napišite svoj Rust kod s vanjskim funkcijama deklariranim kao #[no-mangle].
  3. Izgradite kôd pomoću gornjeg lanca alata.

(Za detaljan pregled gornjih koraka pogledajte knjigu Rust and WebAssembly na GitHubu.)

Vrijedno je napomenuti da, bez obzira na jezik koji upotrebljavate, morat ćete imati barem minimalnu razinu znanja JavaScript-a radi integracije koda s HTML prednjim dijelom. Ako vam se isječci JavaScript na stranici u ovom primjeru iz Rust and WebAssembly Book čine grčkim, odvojite malo vremena za učenje barem toliko JavaScript-a da biste razumjeli što se tamo događa.

Integracija WebAssembly i JavaScript vrši se korištenjem WebAssemblyobjekta u JavaScriptu za stvaranje mosta na vašem WebAssembly kodu. Mozilla ima dokumentaciju o tome kako to učiniti. Evo zasebnog primjera WebAssembly za Rust, a ovdje je primjer WebAssembly za Node.js.

Trenutno je integracija između WebAssembly stražnjeg dijela i JavaScript / HTML prednjeg dijela i dalje najsamariji i najpriručniji dio cijelog procesa. Na primjer, s Rustom, mostovi na JavaScript-u i dalje se moraju stvarati ručno putem pokazivača neobrađenih podataka.

Međutim, više dijelova lanca alata počinje rješavati ovaj problem. Okvir Cheerp omogućuje programerima C ++-a da razgovaraju s API-jema preglednika putem namjenskog prostora imena. A Rust nudi wasm-bindgen, koji služi kao dvosmjerni most između JavaScript-a i Rust-a te između JavaScript-a i WebAssembly-a.

Uz to, u razmatranju je prijedlog visoke razine kako postupati s vezama za domaćina. Kada se finalizira, pružit će standardni način za interakciju jezika s hostovima koji se prevode u WebAssembly. Dugoročna strategija s ovim prijedlogom također obuhvaća vezanje za hostove koji nisu preglednici, ali vezivanja preglednika su kratkoročni slučaj neposredne upotrebe.

Otklanjanje pogrešaka i profiliranje aplikacija WebAssembly

Jedno od područja u kojima je WebAssembly alat još uvijek u najranijoj fazi je podrška za uklanjanje pogrešaka i profiliranje. 

Dok se nisu pojavile izvorne mape JavaScript-a, jezike koji su kompajlirani u JavaScript često je bilo teško otkloniti pogreške jer se izvorni i kompilirani kod nisu mogli lako povezati. WebAssembly ima iste probleme: Ako kod napišete na C i prevedete u WASM, teško je povući korelacije između izvora i kompajliranog koda.

Izvorne mape JavaScript-a pokazuju koje linije u izvornom kodu odgovaraju kojim regijama kompiliranog koda. Neki alati WebAssembly, poput Emscripten, također mogu emitirati JavaScript izvorne mape za kompilirani kôd. Jedan od dugoročnih planova za WebAssembly je izvorni sustav mapa koji nadilazi ono što je dostupno u JavaScript-u, ali još je uvijek u fazi prijedloga.

Trenutno je najizravniji način ispravljanja WASM koda u divljini pomoću konzole za otklanjanje pogrešaka web preglednika. Ovaj članak na WebAssemblyCode pokazuje kako generirati WASM kôd s izvornom mapom, učiniti ga dostupnim alatima za otklanjanje pogrešaka preglednika i proći kroz kôd. Imajte na umu da opisani koraci ovise o korištenju emccalata za emitiranje WASM-a. Možda ćete trebati izmijeniti korake ovisno o vašem lancu alata.