Introduzione a WebAssembly in Go

Introduzione a WebAssembly in Go

WebAssembly è una delle moderne tecnologie progettate per l’esecuzione di più lingue sul browser con l’interoperabilità Javascript.

WebAssembly (WASM) è un formato di istruzione binaria indipendente dalla piattaforma per macchine virtuali basate su stack progettato come destinazione di compilazione portatile per linguaggi di programmazione da eseguire su ambienti abilitanti (ad esempio, le app Web e server).

Con WASM, puoi eseguire diversi linguaggi di programmazione, incluso Go, sul tuo browser e sfruttare le funzionalità del linguaggio. Inoltre, interagisci con Javascript sul web.

Introduzione a WebAssembly in Go

Go fornisce un supporto di prima classe per l’utilizzo di WebAssembly nelle tue applicazioni Go, devi solo effettuare alcune configurazioni e compilare il codice Go in WebAssembly.

Dovrai effettuare alcune configurazioni per trasferire il tuo codice Go in WebAssembly. Dovrai modificare la variabile di ambiente GOARCH dell’architettura Go in wasm e la variabile GOOS del sistema operativo Go in js .

Esegui questo comando nel terminale della tua directory di lavoro per effettuare queste configurazioni.

Set GOARCH=wasm GOOS=js

Il passaggio successivo consiste nel transpilare il codice Go in un file .wasm di WebAssembly . Esegui questo comando per transpilare il tuo file main.go in un file denominato lib.wasm

go build -o lib.wasm main.go

Eseguendo il comando, troverai un file lib.wasm nella tua directory di lavoro.

Devi copiare il file WebAssembly che accompagna l’installazione di Go nella tua directory di lavoro per eseguire il file WebAssembly con NodeJS su una pagina web.

cp "$(go env GOROOT)/misc/wasm/wasm_exec.js".

Il comando copia il file wasm_exec.js nella tua directory di lavoro e funge da punto di ingresso per la tua applicazione.

Ora puoi utilizzare lo script wasm_exec.js per eseguire i tuoi file WASM con Go ed effettuare chiamate API DOM.

node wasm_exec.js main.wasm

Avvio di un server Web per ospitare il sito Web

Aggiungi questo codice dagli autori di Go a un file HTML nella tua directory di lavoro per creare un’istanza di un flusso di dati WebAssembly con il metodo instantiateStreaming .

<!DOCTYPE html>
<!--
Copyright 2018 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->

<html>
<head>
    <meta charset="utf-8" />
    <title>Go wasm</title>
</head>

<body>
<script src="wasm_exec.js"></script>

<script>
    if (!WebAssembly.instantiateStreaming) {
        // polyfill
        WebAssembly.instantiateStreaming = async (resp, importObject) => {
            const source = await (await resp).arrayBuffer();
            return await WebAssembly.instantiate(source, importObject);
        };
    }

    const go = new Go();

    let mod, inst;

    WebAssembly.instantiateStreaming(fetch("lib.wasm"), go.importObject).then(
        result => {
            mod = result.module;
            inst = result.instance;
            document.getElementById("runButton").disabled = false;
        }
    );

    async function run() {
        await go.run(inst);
        inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
    }
</script>

<button onClick="run();" id="runButton" disabled>Run</button>
</body>
</html>

Il codice HTML proviene dagli autori Go, per creare un’istanza di un flusso WebAssembly che collega il codice Go alla pagina Web.

Avvio di un server Web per eseguire la pagina

Configurare il server con il pacchetto http . Importa il pacchetto http e il pacchetto di log per registrare eventuali errori nella console.

import (
    "log"
    "net/http"
)

È possibile dichiarare variabili per l’indirizzo del server e la directory dei file che si desidera servire sull’indirizzo.

var (
    serverAddr = ":8080"
    directory = "."
)

È possibile utilizzare il metodo FileServer del pacchetto http per servire i file in una directory specificata. Il metodo FileServer accetta la directory e restituisce un’istanza del file server.

func main() {
    serveFiles: = http.FileServer(http.Dir(directory))
    if err: = http.ListenAndServe(serverAddr, serveFiles); err! = nil {
        log.Fatalln(err)
}
}

Nella funzione principale , hai dichiarato una variabile di istanza del file server per servire i file nella directory principale. Il metodo ListenAndServe serve i file nella directory specificata sulla porta specificata.

risultato del caricamento di WASM sul browser

Funzioni WebAssembly in Go

Go fornisce funzionalità per chiamare le funzioni JS e interagire con il DOM nel pacchetto syscall/js .

Il pacchetto js fornisce l’accesso agli ambienti host WebAssembly sull’architettura js/wasm . Dovrai impostare il tuo ambiente di sviluppo su GOARCH=wasm GOOS=js per accedere e utilizzare il pacchetto.

js anteprima del documento del pacchetto

Puoi utilizzare i vari metodi nel pacchetto per interagire con la tua pagina web. Ecco come puoi registrare le funzioni con il pacchetto js .

// function definition
func print(this js.Value, i []js.Value) interface{} {
    return js.ValueOf(i[:])
}

La funzione di stampa al momento della registrazione come funzione di richiamata produrrà i dati passati alla funzione nella console del browser.

È possibile registrare le funzioni di richiamata con il metodo Set del metodo Global del pacchetto js . Il metodo Set accetta l’identificatore della funzione e un’istanza della funzione di richiamata.

func RegisterCallbackFunctions() {
    js.Global().Set("print", js.FuncOf(print))
}

Il metodo RegisterCallbackFunctions registra la funzione di stampa come funzione di richiamata che è possibile utilizzare nella console del browser.

WebAssembly è una funzionalità sperimentale in molte lingue, incluso Go

Le funzionalità di WebAssembly sono relativamente nuove per molti linguaggi, specialmente da quando il linguaggio è recentemente diventato uno standard W3C. Il pacchetto js è sperimentale e il pacchetto è esente dalla promessa di compatibilità Go.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *