Programmering

WebAssembly primer: Kom godt i gang med WebAssembly

WebAssembly lover en helt ny type internet - hurtigere ydeevne for brugerne og mere fleksibilitet for udviklere. I stedet for at blive låst til at bruge JavaScript som det eneste sprog til web-interaktion på klientsiden, kan en udvikler vælge fra en bred vifte af andre sprog - C, TypeScript, Rust, Ruby, Python - og arbejde på det sprog, de er mest komfortable med.

Oprindeligt var den eneste måde at oprette WebAssembly på (eller kort sagt WASM) at kompilere C / C ++ - kode til WebAssembly ved hjælp af Emscripten-værktøjskæden. I dag har udviklere ikke kun flere sprogindstillinger, men det er blevet lettere at kompilere disse andre sprog direkte til WebAssembly med færre mellemliggende trin.

I dette stykke undersøger vi de nødvendige trin til implementering af WebAssembly-komponenter i en webapp. Da WebAssembly er et igangværende arbejde, er trinene meget afhængige af hvilket sprog du bruger, og værktøjskæden vil sandsynligvis fortsætte med at ændre sig i nogen tid. Men lige nu er det muligt at skrive og implementere nyttige, hvis minimale, WebAssembly-applikationer på en række sprog.

Vælg et sprog, der understøttes af WebAssembly

Det første skridt mod implementering af en WebAssembly-applikation er at vælge et sprog, der kan kompileres til WebAssembly som et mål. Der er en god chance for, at mindst et af de største sprog, du bruger i produktionen, kan konverteres til WebAssembly eller have en compiler, der kan udsende WebAssembly.

Her er frontløberne:

  • C. Naturligvis. Den typiske måde at omdanne C-kode til WebAssembly er via Emscripten, da C-to-Emscripten-to-WebAssembly var den første WebAssembly-værktøjskæde, der fulgte. Men andre værktøjer dukker op. En hel kompilator, Cheerp, er designet specielt til at generere WebAssembly-applikationer fra C / C ++ -koden. Cheerp kan også målrette mod JavaScript, asm.js eller en hvilken som helst kombination af ovenstående. Det er også muligt at bruge Clang-værktøjskæden til at opbygge WebAssembly-nyttelast, selvom processen stadig kræver en hel del manuel løft. (Her er et eksempel.)
  • Rust. Mozillas programmeringssprog til systemer, der er designet til at være både sikkert og hurtigt, er en af ​​de største kandidater til hjemmehørende WebAssemble support. Udvidelser til Rust-værktøjskæden giver dig mulighed for at kompilere direkte fra Rust-kode til WebAssembly. Du skal bruge Rust's om natten værktøjskæde til at udføre WebAssembly-kompilering, så denne funktion skal betragtes som eksperimentel indtil videre.
  • TypeScript. Som standard kompileres TypeScript til JavaScript, hvilket betyder, at det igen kunne kompileres til WebAssembly. AssemblyScript-projektet reducerer antallet af involverede trin, hvilket gør det muligt at kompilere strengt skrevet TypeScript til WebAssembly.

Flere andre sprog begynder at målrette mod WebAssembly, men de er i de meget tidlige stadier. Følgende sprog kan bruges til at opbygge WebAssembly-komponenter, men kun på mere begrænsede måder end C, Rust og TypeScript:

  • D. D-sproget tilføjede for nylig understøttelse af kompilering og linkning direkte til WebAssembly.
  • Java. Java bytecode kan kompileres i forvejen til WebAssembly via TeaVM-projektet. Det betyder nogen sprog, der udsender Java bytecode, kan kompileres til WebAssembly - for eksempel Kotlin, Scala eller Clojure. Imidlertid er mange af Java API'erne, der ikke kan implementeres effektivt i WebAssembly, begrænset, såsom refleksions- og ressource-API'erne, så TeaVM - og dermed WebAssembly - er kun til brug for et undersæt af JVM-baserede apps.
  • Lua. Lua-skriptsproget har en lang historie med brug som et integreret sprog, ligesom JavaScript. Imidlertid er de eneste projekter, der forvandler Lua til WebAssembly, brug af en eksekveringsmotor i browseren: wasm_lua indlejrer en Lua-runtime i browseren, mens Luwa JIT-kompilerer Lua til WebAssembly.
  • Kotlin / Native. Fans af Kotlin-sproget, en spinoff af Java, har ivrigt ventet på den fulde frigivelse af Kotlin / Native, en LLVM-back-end til Kotlin-kompilatoren, der kan producere selvstændige binære filer. Kotlin / Native 0.4 introducerede support til WebAssembly som et kompileringsmål, men kun som et bevis på konceptet.
  • .Net. .Net-sprogene har endnu ikke fuld understøttelse af WebAssembly, men nogle eksperimenter er begyndt. Se Blazor, som kan bruges til at oprette enkeltsidede webapps i .Net via C # og Microsofts “Razor” -syntaks.
  • Nim. Dette kommende sprog kompileres til C, så man kan i teorien kompilere det resulterende C til WebAssembly. Imidlertid er en eksperimentel back-end for Nim kaldet nwasm under udvikling.
  • Andre LLVM-drevne sprog. I teorien kan ethvert sprog, der udnytter LLVM-compiler-rammen, kompileres til WebAssembly, da LLVM understøtter WebAssembly som et af mange mål. Dette betyder dog ikke nødvendigvis, at ethvert LLVM-kompileret sprog kører som det er i WebAssembly. Det betyder bare, at LLVM gør det lettere at målrette WebAssemble.

Alle ovenstående projekter konverterer det oprindelige program eller genereret bytecode til WebAssembly. Men for fortolkede sprog som Ruby eller Python er der en anden tilgang: I stedet for at konvertere appsne selv konverterer man sproget runtime ind i WebAssembly. Programmerne kører derefter som de er på den konverterede runtime. Da mange sprogkørselstimer (inklusive Ruby og Python) er skrevet i C / C ++, er konverteringsprocessen grundlæggende den samme som med ethvert andet C / C ++ - program.

Dette betyder selvfølgelig, at den konverterede køretid skal downloades til browseren, inden applikationer kan køres med den, hvilket bremser belastning og parseringstid. En "ren" WebAssemble-version af en app er mere let. Således er runtime-konvertering i bedste fald et stopgap-mål, indtil flere sprog understøtter WebAssembly som et eksport- eller kompileringsmål.

Integrer WebAssembly med JavaScript

Det næste trin er at skrive kode på det sprog, du har valgt, med en vis opmærksomhed på, hvordan denne kode vil interagere med WebAssembly-miljøet, derefter kompilere den i et WebAssembly-modul (en WASM-binær) og endelig integrere det modul med et eksisterende JavaScript-applikation.

De nøjagtige trin til, hvordan du eksporterer koden til WebAssembly, vil variere enormt afhængigt af værktøjskæden. De vil også afvige noget fra den måde, hvorpå almindelige oprindelige binære filer er bygget til dette sprog. For eksempel skal du i Rust følge flere trin:

  1. Opsæt om natten bygge til Rust, med wasm32-ukendt-ukendt værktøjskæde.
  2. Skriv din Rust-kode med eksterne funktioner erklæret som # [ikke-mangel].
  3. Byg koden ved hjælp af ovenstående værktøjskæde.

(For en detaljeret gennemgang af ovenstående trin, se The Rust and WebAssembly Book på GitHub.)

Det er værd at bemærke, at uanset hvilket sprog du bruger, skal du have mindst et minimum af færdigheder i JavaScript for at integrere koden med en HTML-frontend. Hvis JavaScript-uddragene på siden i dette eksempel fra The Rust and WebAssembly Book synes græske for dig, skal du afsætte lidt tid til at lære mindst nok JavaScript til at forstå, hvad der sker der.

Integrationen af ​​WebAssembly og JavaScript sker ved hjælp af Websamling objekt i JavaScript for at oprette en bro til din WebAssembly-kode. Mozilla har dokumentation for, hvordan man gør dette. Her er et separat eksempel på WebAssembly for Rust, og her er et eksempel på WebAssembly til Node.js.

Lige nu er integrationen mellem WebAssembly-backenden og JavaScript / HTML-fronten stadig den mest besværlige og manuelle del af hele processen. For eksempel med broer skal broer til JavaScript stadig oprettes manuelt via rådatapunkter.

Flere stykker af værktøjskæden begynder dog at løse dette problem. Cheerp-rammen tillader C ++ - programmører at tale med browserens API'er via et dedikeret navneområde. Og Rust tilbyder wasm-bindgen, som fungerer som en tovejsbro mellem JavaScript og Rust og mellem JavaScript og WebAssembly.

Derudover overvejes et højt niveau forslag til, hvordan man håndterer bindinger til værten. Når det er afsluttet, giver det en standard måde for sprog, der kompileres til WebAssembly, at interagere med værter. Den langsigtede strategi med dette forslag omfatter også bindinger til værter, der ikke er browsere, men browserbindinger er den kortsigtede øjeblikkelige brugssag.

Fejlfinding og profilering af WebAssembly-apps

Et område, hvor WebAssembly-værktøjet stadig er i de tidligste faser, er understøttelse af debugging og profilering.

Indtil JavaScript-kildekort kom, var det ofte vanskeligt at fejle sprog, der blev kompileret til JavaScript, fordi den originale og kompilerede kode ikke let kunne korreleres. WebAssembly har nogle af de samme problemer: Hvis du skriver kode i C og kompilerer den til WASM, er det svært at tegne korrelationer mellem kilden og den kompilerede kode.

JavaScript-kildekort angiver, hvilke linjer i kildekoden svarer til hvilke regioner i den kompilerede kode. Nogle WebAssembly-værktøjer, såsom Emscripten, kan også udsende JavaScript-kildekort til kompileret kode. En af de langsigtede planer for WebAssembly er et kildekortsystem, der går ud over, hvad der er tilgængeligt i JavaScript, men det er stadig kun i forslaget.

Lige nu er den mest direkte måde at fejle WASM-kode i naturen på ved hjælp af webbrowserens fejlfindingskonsol. Denne artikel på WebAssemblyCode viser, hvordan man genererer WASM-kode med et kildekort, gør det tilgængeligt for browserens fejlfindingsværktøjer og går igennem koden. Bemærk, at de beskrevne trin afhænger af brugen af emcc værktøj til at udsende WASM. Du skal muligvis ændre trinnene afhængigt af din specifikke værktøjskæde.