Programování

Základní nátěr WebAssembly: Začínáme s WebAssembly

WebAssembly slibuje zcela nový druh webu - rychlejší výkon pro uživatele a větší flexibilitu pro vývojáře. Místo toho, aby byl vývojář uzamčen v používání JavaScriptu jako jediného jazyka pro webovou interakci na straně klienta, si vývojář může vybrat ze široké škály dalších jazyků - C, TypeScript, Rust, Ruby, Python - a pracovat v tom, ve kterém jsou nejpohodlnější s.

Jediným způsobem, jak vytvořit WebAssembly (nebo zkráceně WASM), bylo původně zkompilovat kód C / C ++ do WebAssembly pomocí nástroje Emscripten. Dnes mají vývojáři nejen více jazykových možností, ale je také snazší kompilovat tyto další jazyky přímo do WebAssembly s menším počtem zásahů.

V tomto článku prozkoumáme kroky potřebné k implementaci komponent WebAssembly ve webové aplikaci. Protože WebAssembly je nedokončená výroba, kroky jsou vysoce závislé na tom, jaký jazyk používáte, a řada nástrojů se pravděpodobně bude nějakou dobu stále měnit. Ale právě teď je možné psát a nasazovat užitečné, i když minimální, aplikace WebAssembly v mnoha jazycích.

Vyberte jazyk podporovaný WebAssembly

Prvním krokem k nasazení aplikace WebAssembly je zvolit jazyk, který lze zkompilovat do WebAssembly jako cíl. Existuje velká šance, že alespoň jeden z hlavních jazyků, které používáte v produkci, lze převést na WebAssembly nebo má kompilátor, který může WebAssembly emitovat.

Zde jsou přední účastníci:

  • C. Očividně. Typický způsob, jak převést kód C na WebAssembly, je přes Emscripten, protože C-to-Emscripten-to-WebAssembly byl první řetězec nástrojů WebAssembly, který přišel. Objevují se však i další nástroje. Celý kompilátor, Cheerp, byl vyvinut speciálně pro generování aplikací WebAssembly z kódu C / C ++. Cheerp může také cílit na JavaScript, asm.js nebo na libovolnou kombinaci výše uvedených. Je také možné použít Clang toolchain k sestavení užitečných zatížení WebAssembly, i když tento proces stále vyžaduje hodně ručního zvedání. (Zde je jeden příklad.)
  • Rez. Programovací jazyk systémů Mozilla, navržený tak, aby byl bezpečný i rychlý, je jedním z hlavních kandidátů rodák Podpora WebAssembly. Rozšíření v řetězci nástrojů Rust umožňují kompilaci přímo z Rust kódu do WebAssembly. Musíte použít Rust's noční nástrojová řada k provedení kompilace WebAssembly, takže tuto funkci bychom měli zatím považovat za experimentální.
  • Strojopis. Ve výchozím nastavení se strojopis zkompiluje do JavaScriptu, což znamená, že jej lze zase zkompilovat do WebAssembly. Projekt AssemblyScript snižuje počet příslušných kroků a umožňuje kompilaci přísně zadaného TypeScript do WebAssembly.

Na WebAssembly začíná cílit několik dalších jazyků, ale jsou ve velmi raných fázích. Následující jazyky lze použít k sestavení komponent WebAssembly, ale pouze omezenějšími způsoby než C, Rust a TypeScript:

  • D. Jazyk D nedávno přidal podporu kompilace a propojení přímo s WebAssembly.
  • Jáva. Bajtový kód Java lze předem zkompilovat do WebAssembly prostřednictvím projektu TeaVM. To znamená žádný jazyk, který vydává bajtový kód Java, lze zkompilovat do WebAssembly - například Kotlin, Scala nebo Clojure. Mnoho rozhraní Java API, které nelze efektivně implementovat do WebAssembly, je však omezeno, například rozhraní API pro reflexi a zdroje, takže TeaVM - a tedy WebAssembly - se používá pouze pro podmnožinu aplikací založených na JVM.
  • Lua. Skriptovací jazyk Lua má dlouhou historii použití jako vložený jazyk, stejně jako JavaScript. Jediné projekty, které přeměňují Lua na WebAssembly, však zahrnují použití spouštěcího nástroje v prohlížeči: wasm_lua vloží běhový modul Lua do prohlížeče, zatímco Luwa JIT kompiluje Lua do WebAssembly.
  • Kotlin / Nativní. Fanoušci jazyka Kotlin, spinoff Java, netrpělivě očekávali plné vydání Kotlin / Native, back-end LLVM pro kompilátor Kotlin, který může produkovat samostatné binární soubory. Kotlin / Native 0.4 představil podporu WebAssembly jako cíl kompilace, ale pouze jako důkaz konceptu.
  • .Síť. Jazyky .Net zatím nemají plnohodnotnou podporu WebAssembly, ale některé experimenty již začaly. Podívejte se na Blazor, který lze použít k vytváření jednostránkových webových aplikací v .Net prostřednictvím C # a syntaxe „Razor“ společnosti Microsoft.
  • Nim. Tento nadcházející jazyk se kompiluje do jazyka C, takže teoreticky je možné kompilovat výsledný jazyk C do WebAssembly. Experimentální back-end pro Nim zvaný nwasm je však ve vývoji.
  • Jiné jazyky podporující LLVM. Teoreticky lze do WebAssembly zkompilovat jakýkoli jazyk, který využívá rámec kompilátoru LLVM, protože LLVM podporuje WebAssembly jako jeden z mnoha cílů. To však nutně neznamená, že jakýkoli jazyk kompilovaný LLVM bude běžet tak, jak je, ve WebAssembly. Znamená to jen, že LLVM usnadňuje cílení na WebAssembly.

Všechny výše uvedené projekty převádějí původní program nebo vygenerovaný bytecode na WebAssembly. Ale u interpretovaných jazyků, jako je Ruby nebo Python, existuje jiný přístup: Místo převodu samotných aplikací jeden převádí jazyk runtime do WebAssembly. Programy pak běží tak, jak jsou, na převedeném modulu runtime. Protože mnoho jazykových modulů runtime (včetně Ruby a Python) je napsáno v C / C ++, je proces převodu v zásadě stejný jako u jakékoli jiné aplikace v C / C ++.

To samozřejmě znamená, že převedený běhový modul musí být stažen do prohlížeče, než s ním bude možné spouštět jakékoli aplikace, což zpomalí načítání a časy analýzy. „Čistá“ verze WebAssembly aplikace je lehčí. Převod za běhu je tedy v nejlepším případě měřítkem mezery, dokud více jazyků nepodporuje WebAssembly jako cíl exportu nebo kompilace.

Integrujte WebAssembly s JavaScriptem

Dalším krokem je napsání kódu v jazyce, který jste si vybrali, s určitou pozorností, jak bude tento kód interagovat s prostředím WebAssembly, poté jej zkompilovat do modulu WebAssembly (binární soubor WASM) a nakonec integrovat tento modul do existujícího JavaScriptová aplikace.

Přesné kroky, jak exportovat kód do WebAssembly, se budou značně lišit v závislosti na řetězci nástrojů. Také se budou trochu odchýlit od způsobu, jakým jsou pro tento jazyk vytvořeny běžné nativní binární soubory. Například v Rustu budete muset provést několik kroků:

  1. Nastavit noční stavět pro Rusta, s wasm32-neznámý-neznámý řetězec nástrojů.
  2. Napište svůj Rust kód s externími funkcemi deklarovanými jako # [no-mangle].
  3. Vytvořte kód pomocí výše uvedeného řetězce nástrojů.

(Podrobný přehled výše uvedených kroků najdete v knize The Rust and WebAssembly Book na GitHubu.)

Stojí za zmínku, že bez ohledu na jazyk, který používáte, budete potřebovat alespoň minimální úroveň znalostí jazyka JavaScript, abyste mohli integrovat kód do rozhraní HTML. Pokud se vám fragmenty kódu JavaScript na stránce v tomto příkladu z knihy The Rust and WebAssembly Book zdají řecké, vyhraďte si nějaký čas na to, abyste se naučili alespoň tolik JavaScriptu, abyste pochopili, co se tam děje.

Integrace WebAssembly a JavaScriptu se provádí pomocí WebAssembly objekt v JavaScriptu k vytvoření mostu k vašemu kódu WebAssembly. Mozilla má dokumentaci, jak to udělat. Zde je samostatný příklad WebAssembly pro Rust a zde je příklad WebAssembly pro Node.js.

Právě teď je integrace mezi back-endem WebAssembly a frontendem JavaScriptu / HTML stále nejtěžší a manuální částí celého procesu. Například u Rustu musí být mosty k JavaScriptu stále vytvářeny ručně, pomocí ukazatelů surových dat.

Tento problém však začíná řešit více částí řetězce nástrojů. Rámec Cheerp umožňuje programátorům C ++ hovořit s API prohlížeče prostřednictvím vyhrazeného prostoru jmen. A Rust nabízí wasm-bindgen, který slouží jako obousměrný most mezi JavaScriptem a Rustem a mezi JavaScriptem a WebAssembly.

Kromě toho se zvažuje návrh na vysoké úrovni, jak zacházet s vazbami na hostitele. Po dokončení poskytne standardní způsob interakce jazyků, které kompilují s WebAssembly s hostiteli. Dlouhodobá strategie s tímto návrhem zahrnuje také vazby na hostitele, kteří nejsou prohlížeči, ale vazby prohlížeče jsou krátkodobým případem okamžitého použití.

Ladění a profilování aplikací WebAssembly

Jednou z oblastí, kde je nástroj WebAssembly stále v nejranějších fázích, je podpora ladění a profilování.

Dokud se neobjevily zdrojové mapy JavaScriptu, bylo obtížné ladit jazyky, které byly zkompilovány do JavaScriptu, protože původní a zkompilovaný kód nebylo možné snadno korelovat. WebAssembly má některé stejné problémy: Pokud píšete kód v jazyce C a kompilujete jej do WASM, je těžké kreslit korelace mezi zdrojem a kompilovaným kódem.

Zdrojové mapy JavaScriptu označují, které řádky ve zdrojovém kódu odpovídají kterým oblastem kompilovaného kódu. Některé nástroje WebAssembly, například Emscripten, mohou také generovat zdrojové mapy JavaScriptu pro kompilovaný kód. Jedním z dlouhodobých plánů pro WebAssembly je systém zdrojových map, který jde nad rámec toho, co je k dispozici v JavaScriptu, ale stále je pouze ve fázi návrhu.

Právě teď je nejpřímější způsob ladění kódu WASM ve volné přírodě pomocí ladicí konzoly webového prohlížeče. Tento článek na WebAssemblyCode ukazuje, jak vygenerovat kód WASM pomocí zdrojové mapy, zpřístupnit jej ladicím nástrojům prohlížeče a projít kód. Všimněte si, že popsané kroky závisí na použití emcc nástroj k vysílání WASM. Možná budete muset upravit kroky v závislosti na konkrétním řetězci nástrojů.