Веб-сборка набирает обороты и теперь поддерживается большинством современных браузеров (85%), и сейчас хорошее время для начала, если вы еще этого не сделали, начать работу с Go (Golang для поисковых систем) очень просто, и Опыт работы в этом руководстве не требуется - вы можете узнать больше о том, как работает WASM и зачем его использовать, здесь.

Для начала нам нужно сначала установить GO, вы можете проверить инструкции здесь.
После того, как мы установили Go, нам нужно создать новый каталог и в нем создать несколько исходных файлов (вы можете просто клонировать репо ):

Мы используем функцию WebAssembly.instantiateStreaming для запуска кода wasm и используем загрузчик go для запуска нашего кода wasm.

Наш main.go файл прост: мы импортируем пакет fmt, который имеет функции, аналогичные console.log (для нашего использования), и по умолчанию он будет печатать на нашей консоли, и у нас есть функция с именем main, каждый проект Go начинается с основной функции , и как только код будет загружен через wasm, эта функция запустится и напечатает «Hello, WebAssembly!» к консоли.

Теперь, когда у нас есть исходные файлы, нам нужно получить файл «wasm_exec.js», который позволит нам загрузить код wasm для go (это то, что дает нам класс Go, который мы используем в файле index.html), мы можем получить его, скопировав из корневых файлов go.

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

Теперь мы можем компилировать или кодировать из main.go, мы компилируем в среду выполнения js (GOOS) и используем архитектуру wasm (GARCH) и выводим результат в main.wasmfile.

GOOS=js GOARCH=wasm go build -o main.wasm

Теперь у нас должен быть файл с именем main.wasm, это файл, содержащий код веб-сборки, который мы будем запускать.

Теперь мы можем использовать любой HTTP-сервер для запуска нашего кода, я использую для него http-сервер, и мы должны увидеть нашу строку, зарегистрированную в консоли.

Именованные функции

Теперь, когда у нас есть простой рабочий код wasm, мы можем начать работу с именованными функциями, мы хотим экспортировать некоторые функции из нашего кода Go, чтобы мы могли использовать их в нашем коде javascript.

Чтобы привязать наш код Go к среде выполнения JS, Go предоставляет нам пакет syscall/js, который мы можем импортировать и использовать для привязки функции к глобальному окну.
Как видите, наш импорт предоставляет переменную с именем js и мы можем получить Global, которое является окном (для браузеров), и мы можем установить функцию с помощью Set, функция называется добавить, и мы используем js.NewCallback, чтобы превратить нашу функцию Go в функцию javascript.

Пока не обращайте внимания на строки с done, они используются здесь для предотвращения выхода из программы Go (путем создания канала Go и ожидания получения данных).

Давайте реализуем функцию с именем «add» в нашем коде Go, который будет принимать два числа и складывать их:

// accept any number of javascript values as arguments
func add(args []js.Value) {
  
  // convert the JS values to Integers (numbers)
  var a = args[0].Int()
  var b = args[1].Int()
  // print the sum of the numbers
  fmt.Println(a + b)
}

Итак, наш полный main.go теперь выглядит так:

Теперь мы можем вызвать функцию window.add(1,2) в нашем коде javascript.

Передача значений из Go в Javascript

Это хорошо, и это то, о чем будет рассказано в большинстве руководств, но мы хотим получить сумму, а не выводить ее на консоль.

Поскольку интерфейс js.NewCallback не позволяет нам возвращать значения, а функции вызываются асинхронно, мы можем использовать старые добрые обратные вызовы, а позже использовать их как обещания, это функция go, которую мы будем использовать для вызова обратного вызова, она принимает массив значений js, возвращаемое значение («интерфейс {}» в основном означает любой тип) и ошибку (если таковая существует).

func execCallback(args []js.Value, value interface{}, e error) {
   // get the last value
   var last = args[len(args) - 1]
   // if the last argument is a function, invoke it
   if last.Type() == js.TypeFunction {
     last.Invoke(e, value)
   } else {
     println("no callback")
  }
}

И теперь наш main.go файл будет выглядеть так:

И когда мы перестроим его и перезагрузим веб-страницу, мы сможем вызвать add следующим образом:

add(5, 10, (sum, error) => console.log(sum));

Мы можем превратить этот вызов в обещание, чтобы упростить нам задачу, это наш новый код js:

Очистка глобальной области видимости

Мы заканчиваем функциями, которые ограничены глобальной областью видимости, давайте вместо этого привяжем их к локальной области (любому объекту).

Я добавил функцию с именем register, которую нам нужно будет вызвать с объектом, и назначить ее функции javascript с именем __wasm_main, мы привяжем все другие функции к этому объекту и будем использовать их оттуда, что означает, что мы вызываем меньшее загрязнение глобальной сфера.

А теперь немного изменим наш js-код:

Что дальше?

Существует несколько загрузчиков Webpack WASM для Go, и вы можете использовать их для добавления Go в свой рабочий процесс внешнего интерфейса, а также есть очень интересный интерфейсный фреймворк, очень похожий на Vue, под названием vugu, который позволяет создавать прекрасный интерфейс. с помощью WASM и Go. Если вы не знаете го и хотите продолжить его изучение, я рекомендую совершить тур по го.