go-wasm-hello-world.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Exit on any error | |
set -e | |
echo "🚀 Starting Go WASM Hello World setup..." | |
# Check if Go is installed, if not install it | |
if ! command -v go &> /dev/null; then | |
echo "📦 Installing Go..." | |
sudo apt-get update | |
sudo apt-get install -y golang-go | |
fi | |
# Create project structure | |
PROJECT_DIR="go-wasm-hello" | |
mkdir -p $PROJECT_DIR/{cmd/server,wasm,static} | |
cd $PROJECT_DIR | |
# Initialize Go module | |
echo "📝 Initializing Go module..." | |
go mod init go-wasm-hello | |
# Create main.go for WASM | |
echo "📝 Creating WASM source file..." | |
cat > wasm/main.go << 'EOF' | |
package main | |
import ( | |
"syscall/js" | |
) | |
func main() { | |
// Get document object | |
doc := js.Global().Get("document") | |
// Create elements | |
container := doc.Call("createElement", "div") | |
heading := doc.Call("createElement", "h1") | |
// Set content and styles | |
heading.Set("innerText", "Hello from Go + WebAssembly! 👋") | |
container.Get("style").Set("textAlign", "center") | |
container.Get("style").Set("marginTop", "50px") | |
heading.Get("style").Set("color", "#2196F3") | |
heading.Get("style").Set("fontFamily", "Arial, sans-serif") | |
// Append elements | |
container.Call("appendChild", heading) | |
doc.Get("body").Call("appendChild", container) | |
// Keep the Go program running | |
select {} | |
} | |
EOF | |
# Create server.go with absolute path handling | |
echo "📝 Creating server file..." | |
cat > cmd/server/main.go << 'EOF' | |
package main | |
import ( | |
"log" | |
"net/http" | |
"os" | |
"path/filepath" | |
) | |
func main() { | |
// Get the executable's directory | |
exe, err := os.Executable() | |
if err != nil { | |
log.Fatal(err) | |
} | |
exeDir := filepath.Dir(exe) | |
// Construct path to static directory | |
staticDir := filepath.Join(exeDir, "static") | |
// Create file server | |
fs := http.FileServer(http.Dir(staticDir)) | |
// Handle all routes | |
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | |
// Set WASM mime type if needed | |
if filepath.Ext(r.URL.Path) == ".wasm" { | |
w.Header().Set("Content-Type", "application/wasm") | |
} | |
fs.ServeHTTP(w, r) | |
}) | |
log.Printf("Serving files from: %s\n", staticDir) | |
log.Println("Server starting on http://localhost:8080 🚀") | |
if err := http.ListenAndServe(":8080", nil); err != nil { | |
log.Fatal(err) | |
} | |
} | |
EOF | |
# Create index.html | |
echo "📝 Creating HTML file..." | |
cat > static/index.html << 'EOF' | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Go WASM Hello World</title> | |
<style> | |
body { | |
background-color: #f5f5f5; | |
margin: 0; | |
padding: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<script src="wasm_exec.js"></script> | |
<script> | |
if (!WebAssembly.instantiateStreaming) { | |
WebAssembly.instantiateStreaming = async (resp, importObject) => { | |
const source = await (await resp).arrayBuffer(); | |
return await WebAssembly.instantiate(source, importObject); | |
}; | |
} | |
const go = new Go(); | |
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject) | |
.then((result) => { | |
go.run(result.instance); | |
}) | |
.catch((err) => { | |
console.error('Failed to load WASM :', err); | |
}); | |
</script> | |
</body> | |
</html> | |
EOF | |
# Copy wasm_exec.js from Go installation | |
echo "📦 Copying wasm_exec.js..." | |
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" static/ | |
# Download required Go modules | |
echo "📦 Downloading Go dependencies..." | |
go mod tidy | |
# Compile the Go program to WASM | |
echo "🔨 Compiling Go to WASM..." | |
pushd wasm | |
GOOS=js GOARCH=wasm go build -o ../static/main.wasm | |
popd | |
# Build the server | |
echo "🔨 Building server..." | |
pushd cmd/server | |
go build -o ../../server | |
popd | |
# Create a deployment directory | |
echo "📦 Creating deployment directory..." | |
DEPLOY_DIR="deploy" | |
mkdir -p $DEPLOY_DIR | |
cp server $DEPLOY_DIR/ | |
cp -r static $DEPLOY_DIR/ | |
# Install process manager if not installed | |
if ! command -v pm2 &> /dev/null; then | |
echo "📦 Installing PM2 process manager..." | |
# Install Node.js and npm if not present | |
if ! command -v npm &> /dev/null; then | |
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - | |
sudo apt-get install -y nodejs | |
fi | |
sudo npm install - g pm2 | |
fi | |
# Stop any existing instance | |
pm2 stop go-wasm-server 2>/dev/null || true | |
pm2 delete go-wasm-server 2>/dev/null || true | |
# Start the server with PM2 from the deployment directory | |
echo "🚀 Starting server..." | |
cd $DEPLOY_DIR | |
pm2 start ./server --name go-wasm-server | |
echo "✨ Setup complete! Your Go WASM Hello World is running at http://localhost:8080" | |
echo "📝 PM2 Logs: pm2 logs go-wasm-server" | |
echo "⏹️ To stop: pm2 stop go-wasm-server" |