Compilación con GOOS=wasip1 GOARCH=wasm
El destino WASI de Go convierte paquetes ordinarios en módulos .wasm portátiles.
Busca en todas las páginas de la documentación
El destino WASI de Go convierte paquetes ordinarios en módulos .wasm portátiles.
El comando de compilación es similar a la compilación cruzada a Linux o Windows: configura GOOS y GOARCH, y luego go build.
Comprender qué flags son importantes y qué archivos (wasm_exec.js) pertenecen a un destino diferente mantiene correctos tus scripts de compilación y matrices de CI.
GOOS=wasip1 con GOARCH=wasm selecciona la superficie de llamadas al sistema WASI Preview 1.
El enlazador de Go emite un módulo que importa funciones de wasi_snapshot_preview1 en lugar de llamadas al sistema específicas de la plataforma.
Ejecutas el artefacto con un host WASM externo (wasmtime, wazero, Spin) en lugar del comando go.
Las compilaciones de lanzamiento comúnmente pasan -ldflags="-s -w" para eliminar metadatos de depuración.
Las notas sobre wasm_exec.js para destinos de navegador no se aplican a la salida wasip1.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
GOOS=wasip1 GOARCH=wasm go build -ldflags="-s -w" -o app.wasm .
wasmtime run app.wasmCuándo usar esto:
.wasmpackage main
import (
"encoding/json"
"fmt"
"os"
)
type config struct {
Name string `json:"name"`
}
func main() {
raw := os.Getenv("CONFIG_JSON")
if raw == "" {
fmt.Fprintln(os.Stderr, "CONFIG_JSON required")
os.Exit(1)
}
var cfg config
if err := json.Unmarshal([]byte(raw), &cfg); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
fmt.Printf("hello, %s\n", cfg.Name)
}go mod init example.com/wasigreet
# guarda main.go, luego:
GOOS=wasip1 GOARCH=wasm go build -ldflags="-s -w" -o greet.wasm .
wasmtime run --env CONFIG_JSON='{"name":"Ada"}' greet.wasmLo que esto demuestra:
encoding/json, os) se compilan para WASI sin tags.--env en wasmtime).os.Stderr se mapea a los streams stderr del host.wasip1 mapea las operaciones de archivo de os a las APIs de fd de WASI que el host debe implementar._start es el punto de entrada que el host llama después de instanciar la memoria lineal.go mod y el vendoring funcionan igual que las compilaciones nativas; cgo no está disponible en este destino.| Variable / Flag | Propósito |
|---|---|
GOOS=wasip1 | Selecciona la ABI de llamadas al sistema WASI Preview 1 |
GOARCH=wasm | Selecciona la arquitectura WebAssembly |
-ldflags="-s -w" | Elimina tablas de símbolos/depuración para binarios más pequeños |
GOWASM=... | Históricamente alternaba características de WASM; signext/satconv ignorados en Go 1.26 |
GOFLAGS=-trimpath | Compilaciones reproducibles sin rutas de host incrustadas |
| Artefacto | Destino | Cómo ejecutar |
|---|---|---|
app.wasm | wasip1/wasm | wasmtime run, incrustado en wazero, despliegue en Spin |
main.wasm + wasm_exec.js | js/wasm | Navegador o Node con shim de tiempo de ejecución JS |
No copies GOROOT/misc/wasm/wasm_exec.js en los paquetes de despliegue WASI.
// Archivos de entrada de navegador separados - nunca compiles estos en compilaciones wasip1.
//go:build js && wasm
package browseronly# Patrón de Makefile
build-wasi:
GOOS=wasip1 GOARCH=wasm go build -ldflags="-s -w" -o bin/app.wasm ./cmd/appAsumir que go run funciona - No hay un emulador WASI dentro de go run; debes ejecutar con un host WASM. Solución: envuelve wasmtime run o wazero en objetivos go:generate/Makefile.
Escrituras en el sistema de archivos sin pre-apertura - os.Create("/tmp/x") falla si el host no mapeó /tmp. Solución: pasa wasmtime run --dir /host/tmp::/tmp o configura wazero FSConfig.
Mezclar archivos js/wasm en paquetes WASI - Las importaciones accidentales de syscall/js rompen la compilación wasip1. Solución: aisla el código del navegador detrás de los tags de compilación js && wasm.
Esperar red completa - WASI preview 1 no garantiza APIs de TCP en todos los tiempos de ejecución. Solución: confirma el soporte de sockets o usa triggers HTTP de Spin.
Binarios enormes por sorpresa - El tiempo de ejecución completo de Go añade megabytes incluso para fmt.Println. Solución: mide el tamaño pronto; considera TinyGo o divide las rutas "calientes".
GOOS=wasi obsoleto - Documentación más antigua hace referencia a wasi; las herramientas modernas usan wasip1. Solución: actualiza los scripts a wasip1 para Go 1.21+.
| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
GOOS=js GOARCH=wasm | Interoperabilidad DOM/fetch en navegadores | Servidores sin cabeza o incrustación en wazero |
TinyGo -target=wasm | Presupuestos estrictos de tamaño | Necesitas bibliotecas completas con mucho reflect/generics |
GOOS=linux nativo | Máximo rendimiento y cobertura de llamadas al sistema | Necesitas plugins portátiles en sandbox |
Rust wasm32-wasi | El tamaño mínimo del binario es primordial | El estándar del equipo es Go y la cobertura de la biblioteca estándar importa |
Go 1.21 estabilizó GOOS=wasip1 como el destino WASM del servidor.
Go 1.26 optimiza aún más la fragmentación del heap de WASM y la reducción de instrucciones de WASM.
No. Deshabilita cgo (CGO_ENABLED=0, el valor predeterminado para compilaciones cruzadas) y mantén las dependencias en Go puro.
WASI mapea los argumentos a os.Args.
wasmtime run app.wasm arg1 arg2 los popula como un proceso normal.
Sí. Los tags de compilación todavía dividen archivos; usa archivos específicos de wasip1 cuando necesites rutas de código solo para el destino.
Mantén una compilación paralela GOOS=linux para Delve, y usa wasmtime run con logging para problemas de integración.
Las compilaciones DWARF sin strip son más grandes pero pueden ayudar a depuradores WASM avanzados.
El enlace dinámico de WASM depende del host.
La mayoría de los equipos compilan un módulo por plugin y exponen una ABI estrecha (por ejemplo, JSON a través de stdin/stdout).
Ese es el destino del navegador, no WASI.
Produce importaciones diferentes y requiere wasm_exec.js.
Sí, bajo el compilador completo de Go.
TinyGo también admite goroutines con un planificador más pequeño, sujeto a sus límites.
Comienza con -ldflags="-s -w", audita las dependencias y evalúa TinyGo.
Go 1.26 reduce la memoria del tiempo de ejecución, no necesariamente el tamaño del archivo en disco.
go test no ejecuta pruebas WASI de forma nativa.
Compila binarios de prueba a WASM y ejecútalos bajo wasmtime, o mantén las pruebas de lógica en linux/amd64 y las pruebas de humo de WASM en CI.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (Green Tea GC por defecto, go fix modernizers - verifica el parche en la compilación), chi (última versión - verifica en la compilación), gin (última versión - verifica en la compilación), echo (última versión - verifica en la compilación), google.golang.org/grpc (última versión - verifica en la compilación), sigs.k8s.io/controller-runtime (última versión - verifica en la compilación), kubebuilder (última versión - verifica en la compilación), tinygo (última versión - verifica los objetivos de placa en la compilación), wazero (última versión - verifica en la compilación), y golangci-lint (última versión - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026