
Ενσωμάτωση της βιβλιοθήκης Go σε μια ιστοσελίδα JavaScript με το WebAssembly
Με το WebAssembly μπορείτε να ενσωματώσετε διαφορετικές γλώσσες προγραμματισμού μαζί. Αυτό ανοίγει νέες δυνατότητες για τη χρήση σπουδαίων βιβλιοθηκών γραμμένων σε μια γλώσσα σε μια άλλη διαφορετική πλατφόρμα. Σε αυτό το άρθρο θέλω να σας δείξω πώς να ενσωματώσετε μια βιβλιοθήκη Go για τη συμβολοποίηση προτάσεων σε μια ιστοσελίδα JavaScript. Κανονικά, δεν μπορείτε να εκτελέσετε κώδικα Go σε ένα πρόγραμμα περιήγησης ιστού, αλλά με την τεχνολογία WebAssembly μπορείτε.
Το WebAssembly
WebAssembly είναι μια προδιαγραφή του W3C που ορίζει μια δυαδική μορφή και μορφή κειμένου για εκτελέσιμα προγράμματα που μπορούν να τρέξουν στο πρόγραμμα περιήγησης αλλά και αυτόνομα. Τα προγράμματα WebAssembly εκτελούνται σε μια εικονική μηχανή (VM) βασισμένη σε στοίβα. Παίρνοντας το όνομά του από τη γλώσσα προγραμματισμού Assembly, η οποία είναι πολύ κοντά στο πραγματικό υλικό, το WebAssembly ορίζει μια γλώσσα πιο ανεξάρτητη από τη συσκευή από ό,τι η Assembly, αλλά εξακολουθεί να είναι πολύ χαμηλού επιπέδου. Κατά τη στιγμή της συγγραφής αυτού του άρθρου, το WebAssembly υποστηρίζεται από το 97,11 % όλων των παγκόσμιων προγραμμάτων περιήγησης (caniuse.com). Υπάρχουν διάφορες επεκτάσεις στην προδιαγραφή WebAssembly του W3C, οι οποίες έχουν διαφορετικά επίπεδα υποστήριξης μεταξύ των φυλλομετρητών.
Sentences Go Library
Sentences είναι μια βιβλιοθήκη Go για τη συμβολαιοποίηση προτάσεων που γράφτηκε από τον Eric Bower και δημοσιεύτηκε ως ανοιχτός κώδικας στο GitHub. Δεδομένου ότι δεν μπορείτε να εκτελέσετε κώδικα Go στο πρόγραμμα περιήγησης εγγενώς, παρά μόνο JavaScript, υπάρχει η ιδέα της χρήσης του WebAssembly για την ενσωμάτωση της βιβλιοθήκης σε έναν ιστότοπο.
Έκθεση της βιβλιοθήκης Sentences σε JavaScript
Μπορείτε να ενσωματώσετε τη βιβλιοθήκη sentences γράφοντας μια εφαρμογή περιτύλιξης Go που αξιοποιεί το πακέτο syscall/js της Go. Αποτελεί μέρος της τυπικής βιβλιοθήκης της Go. Σημειώστε, ότι κατά τη στιγμή της συγγραφής αυτού του άρθρου, το πακέτο αυτό είναι χαρακτηρισμένο ως "πειραματικό". Συγκεκριμένα, θα χρησιμοποιήσουμε τη συνάρτηση js.FuncOf. Ακολουθεί ο πλήρης πηγαίος κώδικας της εφαρμογής Go:
package main
import (
"fmt"
"strings"
"syscall/js"
"github.com/neurosnap/sentences/english"
)
func sentenceWrapper() js.Func {
sentenceFunc := js.FuncOf(func(this js.Value, args []js.Value) any {
if len(args) != 1 {
return "Invalid no of arguments passed"
}
inputSentence := args[0].String()
fmt.Printf("input %s\n", inputSentence)
tokenizer, err := english.NewSentenceTokenizer(nil)
if err != nil {
panic(err)
}
sentences := tokenizer.Tokenize(inputSentence)
for _, s := range sentences {
fmt.Println(s.Text)
}
var sentenceTexts []string
for _, s := range sentences {
trimmedText := strings.TrimSpace(s.Text)
sentenceTexts = append(sentenceTexts, trimmedText)
}
allSentences := strings.Join(sentenceTexts, "\n") // Join all sentences separated by a space
return allSentences
})
return sentenceFunc
}
func main() {
fmt.Println("Go Web Assembly")
js.Global().Set("tokenizeSentence", sentenceWrapper())
<-make(chan struct{})
}
Βλέπετε ότι τώρα η συνάρτηση sentenceWrapper εκτίθεται ως η συνάρτηση tokenizeSentence στην JavaScript. Αναμένει ως όρισμα ένα αλφαριθμητικό για tokenize και επιστρέφει το tokenized αλφαριθμητικό. Η πραγματική ενσωμάτωση με τη βιβλιοθήκη sentences γίνεται μέσα στη συνάρτηση που περνάει στη js.FuncOf.
Μεταγλώττιση Wrapper
Μεταγλωττίζετε την εφαρμογή σε WebAssembly χρησιμοποιώντας την ακόλουθη εντολή κατασκευής Go:
GOOS=js GOARCH=wasm go build -o main.wasm
Αν όλα πήγαν καλά, θα πρέπει να βρείτε το αρχείο main.wasm ως έξοδο στο φάκελό σας. Αυτό είναι το δυαδικό αρχείο WebAssembly που θα φορτωθεί στην εφαρμογή JavaScript.
Ενσωμάτωση της βιβλιοθήκης WebAssembly Go στην ιστοσελίδα
Για να φορτώσετε το αρχείο main.wasm στην ιστοσελίδα, χρειάζεστε τον ακόλουθο κώδικα:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(
fetch("./main.wasm"),
go.importObject
).then((result) => {
go.run(result.instance);
});
</script>
</head>
<body>
<textarea id="sentenceinput" name="jsoninput" cols="80" rows="20"></textarea>
<input
id="button"
type="submit"
name="button"
value="tokenize"
onclick="tokenize(sentenceinput.value)"
/>
<textarea id="jsonoutput" name="jsonoutput" cols="80" rows="20"></textarea>
</body>
<script>
var tokenize = function (input) {
jsonoutput.value = tokenizeSentence(input);
};
</script>
</html>
Κατά την εκτέλεση αυτής της ιστοσελίδας στο πρόγραμμα περιήγησης, χρειάζεστε επίσης το βοηθητικό αρχείο JavaScript wasm_exec.js στον τρέχοντα κατάλογο. Μπορείτε να πάρετε το αρχείο από τη διεύθυνση:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
Όπως μπορείτε να δείτε από τον κώδικα JavaScript, η εκτεθειμένη συνάρτηση tokenizeSentence() καλείται από τη JavaScript όταν κάνετε κλικ στο κουμπί "tokenize". Τα περιεχόμενα του πεδίου εισαγωγής χρησιμοποιούνται ως όρισμα στη συνάρτηση και η τιμή επιστροφής γράφεται στη συνέχεια στο πεδίο κειμένου στα δεξιά. Σημειώστε ότι πρέπει να εκτελέσετε έναν διακομιστή ιστού για να εκτελέσετε την ιστοσελίδα στο πρόγραμμα περιήγησης. Μπορείτε να χρησιμοποιήσετε αυτόν τον κώδικα για να δημιουργήσετε έναν διακομιστή ιστού σε Go: server/server.go
package main
import (
"fmt"
"net/http"
)
func main() {
err := http.ListenAndServe(":9090", http.FileServer(http.Dir("../")))
if err != nil {
fmt.Println("Failed to start server", err)
return
}
}
Μετά την εκκίνηση του διακομιστή ιστού, μπορείτε να έχετε πρόσβαση στη σελίδα στο πρόγραμμα περιήγησής σας στη διεύθυνση: http://localhost:9090. Ευχαριστώ τον Naveen Ramanathan από το golangbot.com για την έμπνευσή του σε αυτό το άρθρο.
Συμπέρασμα
Όπως πάντα, ελπίζω αυτό το άρθρο να σας βοήθησε με κάποιο τρόπο να παραμείνετε περίεργοι. Το WebAssembly είναι μια τεχνολογία που έχει μεγάλες δυνατότητες να ενσωματώσει τα πολλά διαφορετικά γλωσσικά οικοσυστήματα μεταξύ τους.
Αναφορές
- WebAssembly.org: https://webassembly.org
- WebAssembly specification: https://github.com/WebAssembly/spec
- Go sentences library: https://github.com/neurosnap/sentences
- Syscall/js package: https://pkg.go.dev/syscall/js
- Golangbot Webassembly using Go: https://golangbot.com/webassembly-using-go
Photo by Venti Views on Unsplash
Δημοσιευμένο
23 Ιουλ 2024
