مقدمة إلى WebAssembly وGo
WebAssembly (Wasm) هو تنسيق تعليمات ثنائي منخفض المستوى يتم تنفيذه في المتصفح بسرعة شبه أصلية. عند دمجه مع لغة Go (Golang)، تحصل على أداة قوية لإنشاء تطبيقات ويب عالية الأداء. يتم تجميع Go إلى WebAssembly، مما يسمح بنقل الحسابات المعقدة والخوارزميات وحتى الألعاب مباشرة إلى المتصفح، دون التضحية بالأداء.
في هذه المقالة، سنشرح كيفية إعداد البيئة، وكتابة وحدة بسيطة بلغة Go، وتجميعها إلى Wasm، ودمجها مع JavaScript. ستتعرف على الحزم الرئيسية والقيود وأفضل الممارسات.
إعداد البيئة لتجميع Go إلى Wasm
تثبيت Go وتبعيات WebAssembly
أولاً وقبل كل شيء، تأكد من تثبيت Go الإصدار 1.11 أو أحدث (يُوصى بالإصدار 1.21+). WebAssembly مدعوم بشكل افتراضي. للتجميع، يُستخدم متغير البيئة GOOS=wasm GOARCH=wasm.
ستحتاج أيضًا إلى ملف الدعم wasm_exec.js المرفق مع Go. انسخه إلى جذر المشروع:
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .هيكل المشروع
لننشئ هيكلًا بسيطًا:
my-wasm-app/├── main.go├── wasm_exec.js├── index.html└── main.wasm (سيتم إنشاؤه بعد التجميع)كتابة وحدة بلغة Go لـ WebAssembly
مثال بسيط: دالة الجمع
أنشئ ملف main.go بالمحتوى التالي:
package main
import ( "syscall/js")
func add(this js.Value, args []js.Value) interface{} { if len(args) < 2 { return 0 } a := args[0].Int() b := args[1].Int() return a + b}
func main() { c := make(chan struct{}, 0)
js.Global().Set("goAdd", js.FuncOf(add))
<-c}هنا نستخدم الحزمة syscall/js للتفاعل مع JavaScript. الدالة add تأخذ وسيطين وتعيد مجموعهما. القناة c تمنع إنهاء البرنامج ليبقى module نشطًا.
التجميع إلى Wasm
نفذ الأمر:
GOOS=wasm GOARCH=wasm go build -o main.wasm main.goستحصل على ملف main.wasm بحجم حوالي 1–2 ميجابايت (للمثال البسيط). في الإنتاج، استخدم العلم -ldflags="-s -w" لتقليل الحجم.
الدمج مع HTML وJavaScript
إنشاء صفحة HTML
أنشئ ملف index.html:
<!DOCTYPE html><html lang="ar"><head> <meta charset="UTF-8"> <title>Go + WebAssembly</title> <script src="wasm_exec.js"></script></head><body> <h2>آلة حاسبة بلغة Go في المتصفح</h2> <input type="number" id="num1" value="5"> <input type="number" id="num2" value="10"> <button onclick="calculate()">اجمع</button> <p>النتيجة: <span id="result">0</span></p>
<script> const go = new Go(); WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject) .then((result) => { go.run(result.instance); console.log("تم تحميل WebAssembly module"); });
function calculate() { const a = parseInt(document.getElementById('num1').value); const b = parseInt(document.getElementById('num2').value); const sum = goAdd(a, b); document.getElementById('result').innerText = sum; } </script></body></html>لاحظ: الدالة goAdd تصبح عامة بفضل استدعاء js.Global().Set("goAdd", ...) في كود Go.