在Svelte项目中集成Golang/Wasm是可行的方案,以下是具体实现示例:
1. Go/Wasm端代码
// main.go
package main
import (
"syscall/js"
)
func add(this js.Value, args []js.Value) interface{} {
if len(args) != 2 {
return js.ValueOf(nil)
}
a := args[0].Float()
b := args[1].Float()
return js.ValueOf(a + b)
}
func registerCallbacks() {
js.Global().Set("goAdd", js.FuncOf(add))
}
func main() {
c := make(chan struct{}, 0)
registerCallbacks()
<-c
}
编译为Wasm:
GOOS=js GOARCH=wasm go build -o main.wasm main.go
2. Svelte端集成
<!-- App.svelte -->
<script>
let wasmModule;
let result = 0;
let a = 5;
let b = 3;
async function loadWasm() {
const go = new Go();
const response = await fetch('main.wasm');
const bytes = await response.arrayBuffer();
const { instance } = await WebAssembly.instantiate(bytes, go.importObject);
go.run(instance);
wasmModule = instance.exports;
}
function calculate() {
if (window.goAdd) {
result = window.goAdd(a, b);
}
}
onMount(() => {
loadWasm();
});
</script>
<main>
<h1>Go/Wasm + Svelte</h1>
<input type="number" bind:value={a} />
<input type="number" bind:value={b} />
<button on:click={calculate}>计算</button>
<p>结果: {result}</p>
</main>
3. Vite配置(推荐)
// vite.config.js
import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
plugins: [svelte()],
server: {
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp'
}
}
});
4. 使用TinyGo的优化版本
// 使用TinyGo编译(更小的Wasm体积)
// tinygo build -target=wasm -o main.wasm main.go
5. 构建脚本示例
// package.json片段
{
"scripts": {
"build:go": "GOOS=js GOARCH=wasm go build -o public/main.wasm ./wasm",
"dev": "npm run build:go && vite",
"build": "npm run build:go && vite build"
}
}
6. 直接内存操作示例
// 高性能数据交换
func processData(this js.Value, args []js.Value) interface{} {
dataPtr := args[0].Int()
length := args[1].Int()
// 从内存中读取数据
data := make([]byte, length)
js.CopyBytesToGo(data, js.ValueOf(dataPtr))
// 处理数据
for i := range data {
data[i] = data[i] * 2
}
// 写回内存
js.CopyBytesToJS(js.ValueOf(dataPtr), data)
return nil
}
这个方案不需要专门的Svelte插件,通过标准的WebAssembly API即可实现集成。关键点包括正确配置HTTP头以支持Wasm,以及通过JavaScript全局对象进行Go/Svelte间的函数调用。