[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-mdn-webassembly-guide-turns-js-into-a-host-zh":3,"article-related-mdn-webassembly-guide-turns-js-into-a-host-zh":30,"series-tools-0a1c8ca2-a054-4230-9aef-2de8fdd0aaac":82},{"id":4,"slug":5,"title":6,"content":7,"summary":8,"source":9,"source_url":10,"author":11,"image_url":12,"cover_image":12,"category":13,"language":14,"translated_content":11,"related_article_id":15,"keywords":16,"key_takeaways":22,"views":26,"created_at":27,"published_at":28,"topic_cluster_id":29},"0a1c8ca2-a054-4230-9aef-2de8fdd0aaac","mdn-webassembly-guide-turns-js-into-a-host-zh","MDN 讓 Wasm 變成 JS 主機","\u003Cp data-speakable=\"summary\">我把 MDN 的 WebAssembly 指南拆成一套可直接複製的 JavaScript 載入流程，外加一份能立刻貼進專案的 \u003Ca href=\"\u002Fnews\u002Fwasm-one-codebase-many-runtimes-zh\">Wasm\u003C\u002Fa> loader 模板。\u003C\u002Fp>\u003Cp>我用 WebAssembly 一陣子了，但老實說，很多教學都把它講得像性能仙丹，這點我最受不了。第一次把 Wasm 模組接進真實專案時，我踩到的坑其實很無聊：一邊是 build toolchain，一邊是 JavaScript glue，中間還夾著一堆半懂不懂的 \u003Ca href=\"\u002Ftag\u002Fapi\">API\u003C\u002Fa>。文件沒錯，可是讀完還是很難知道到底該先做哪一步。\u003C\u002Fp>\u003Cp>我真正想要的，不是再看一篇「Wasm 很快」的宣傳文，而是知道它跟 JavaScript 到底\u003Ca href=\"\u002Fnews\u002Fhow-to-track-anthropic-events-and-webinars-zh\">怎麼\u003C\u002Fa>分工、什麼情況值得上、以及最短路徑怎麼把一個 module 接進瀏覽器。MDN 的 \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWebAssembly\" rel=\"noopener noreferrer\">WebAssembly guide\u003C\u002Fa> 就是我一直回頭看的來源，因為它至少有把元件講清楚，只是讀起來比較像參考手冊，不像操作菜單。我今天就是要把它翻成能上手的版本。\u003C\u002Fp>\u003Cp>這篇不是要重新發明 WebAssembly。我是把 MDN 的意思拆開，直接告訴你：哪些觀念要先放在腦子裡、哪些 API 真正會用到、哪些地方其實不用想太多。最後我會給你一份可以直接複製的 loader，讓你不用從零拼整個整合流程。\u003C\u002Fp>\u003Cp>來源錨點就是 MDN 這頁本身，\u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWebAssembly\" rel=\"noopener noreferrer\">WebAssembly guide\u003C\u002Fa>，裡面把概念、JavaScript API、text format、以及相關子頁都串在一起。它沒有提供星數或 bookmark 數，我也不硬掰；它提供的是比較有用的東西：結構跟路徑。\u003C\u002Fp>\u003Ch2>先把 Wasm 放回它該待的位置\u003C\u002Fh2>\u003Cblockquote>“WebAssembly is designed to complement and run alongside JavaScript.”\u003C\u002Fblockquote>\u003Cp>翻譯一下就是：Wasm 不是來取代 JavaScript 的。JavaScript 才是主機，負責 DOM、事件、fetch、UI flow、狀態串接；Wasm 是你拿來處理特定重活的模組。這個分工如果搞反，整個專案就會開始長出奇怪的抽象層，然後大家一起痛苦。\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1779973422679-zrjy.png\" alt=\"MDN 讓 Wasm 變成 JS 主機\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cp>MDN 這句話其實很直白，但很多文章會故意講得很玄，好像你只要把 app 搬去 Wasm 就會比較快。我看過不少團隊花很多時間把一小段熱點包進 Wasm，結果真正的瓶頸根本是演算法、資料流，甚至只是 DOM 更新方式太爛。你把框架換成低階語言，問題不會自動消失。\u003C\u002Fp>\u003Cp>我之前遇過一個影像處理 dashboard，某個轉換流程一直卡 UI。最後有效的做法不是「整個前端改成 Wasm」，而是把那段吃 CPU 的數學丟進小模組，其他部分全部留在 JS。這才是 MDN 在暗示你的路線：小範圍、明確邊界、只處理真的值得下放的工作。\u003C\u002Fp>\u003Cp>實操寫法很簡單：先找一個單點任務，最好是 CPU-heavy，或是本來就存在於 C \u002F C++ \u002F \u003Ca href=\"\u002Ftag\u002Frust\">Rust\u003C\u002Fa> \u002F C# 的既有邏輯。把它切成一個明確函式，讓 JS 負責呼叫，Wasm 負責算。你如果沒辦法用一句話說清楚邊界，那通常代表你還不需要 Wasm。\u003C\u002Fp>\u003Cul>\u003Cli>適合：影像處理、壓縮、解析器、加密、物理模擬、既有 native library。\u003C\u002Fli>\u003Cli>不適合：表單互動、路由、DOM 操作、簡單資料轉換。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>binary 不是細節，是整個工作方式\u003C\u002Fh2>\u003Cp>MDN 把 Wasm 說成「low-level assembly-like language with a compact binary format」。這句我覺得很重要，因為它直接點出 Wasm 的本質：你不是在 ship 一份一般意義上的 source code，而是在 ship 一個編譯後的 artifact。瀏覽器吃的是 binary，先驗證、再 instantiate、再執行。\u003C\u002Fp>\u003Cp>白話一點講，Wasm 的世界不是「寫完直接跑」，而是「先編譯，再交給瀏覽器」。所以你要思考的是 build output，不是 runtime source。你的 source 通常在 Rust、C、C++ 或其他編譯語言裡，瀏覽器只是最後的 consumer，不是你的 compiler pipeline。\u003C\u002Fp>\u003Cp>我以前最容易卡住的點，就是盯著 `.wasm` 檔案想把它當成可讀程式碼看。那根本是自找麻煩。MDN 另外提供 text format 的文章與轉換說明，就是因為 binary 本來就不是給人直接讀的。binary 是給機器；text format 才是給你在 debug 或學習時用的。\u003C\u002Fp>\u003Cp>實作上，我會把 Wasm binary 當成一般 build artifact 來管理：進 CI、做版本控制、需要的話做 cache fingerprint，並且確保產物每次都能穩定產出。要看行為就看 text format 或 devtools，不要對著 binary 發呆。\u003C\u002Fp>\u003Cp>如果你想看更底層的標準脈絡，可以看 \u003Ca href=\"https:\u002F\u002Fwebassembly.org\u002F\" rel=\"noopener noreferrer\">WebAssembly project site\u003C\u002Fa>；但如果你是在瀏覽器端整合，MDN 的 API 頁面才是你每天真的會碰到的那層。\u003C\u002Fp>\u003Ch2>JS 是 glue，不是配角，這反而比較正常\u003C\u002Fh2>\u003Cp>MDN 的意思很清楚：WebAssembly module 可以被 JavaScript 載入，兩邊可以共享功能。這就是實際模型。JS 負責載入 module、傳 imports、接 exports，然後把它接回整個 web platform。Wasm 不會幫你處理 DOM，也不會神奇地接管瀏覽器 API。\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1779973430252-4ml7.png\" alt=\"MDN 讓 Wasm 變成 JS 主機\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cp>翻譯一下就是：整合的難點都在邊界。邊界上會出現 imports、exports、memory、table。邊界搞錯，module 就會很彆扭；邊界弄乾淨，後面通常很安靜，這種安靜才是 production 想要的。\u003C\u002Fp>\u003Cp>我自己的經驗是，JS wrapper 越小越好。不要包一層很厚的抽象，不要搞什麼「通用 runtime」，也不要為了看起來優雅就把 boundary 藏起來。你只需要 loader、instance、幾個 exports。MDN 的 \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWebAssembly\u002FJavaScript_interface\" rel=\"noopener noreferrer\">JavaScript API reference\u003C\u002Fa> 之所以有用，就是因為它直接把 \u003Ccode>WebAssembly.Module\u003C\u002Fcode>、\u003Ccode>WebAssembly.Instance\u003C\u002Fcode>、\u003Ccode>WebAssembly.Memory\u003C\u002Fcode>、\u003Ccode>WebAssembly.Table\u003C\u002Fcode> 這些東西講出來，不跟你玩虛的。\u003C\u002Fp>\u003Cp>實操寫法：寫一個單獨的 JS 檔，只負責載入和 wiring。App code 跟 loader 分開。共享狀態要先決定放哪裡：JS、Wasm memory，還是 export function。不要因為 demo 看起來很順，就把所有邊界揉成一團。\u003C\u002Fp>\u003Cul>\u003Cli>JS 用在 I\u002FO、DOM、fetch、事件處理。\u003C\u002Fli>\u003Cli>Wasm 用在可預期、計算密集的工作。\u003C\u002Fli>\u003Cli>能用明確 exports 就別偷塞隱性全域狀態。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>載入路徑選錯，整個體驗就會很煩\u003C\u002Fh2>\u003Cp>MDN 列得很清楚：\u003Ccode>WebAssembly.compile()\u003C\u002Fcode>、\u003Ccode>WebAssembly.compileStreaming()\u003C\u002Fcode>、\u003Ccode>WebAssembly.instantiate()\u003C\u002Fcode>、\u003Ccode>WebAssembly.instantiateStreaming()\u003C\u002Fcode>。如果你是在瀏覽器裡跑，我通常第一個會看 streaming 版本，因為瀏覽器可以邊收 bytes 邊編譯。這不是萬靈丹，但它是合理的預設，前提是你的 server 有把 MIME type 配對好。\u003C\u002Fp>\u003Cp>也就是說，載入策略本身就是設計的一部分。你不是單純「import 一個檔案」而已，你是在選擇要先抓完再編譯，還是邊下載邊編譯。這會直接影響啟動時間、錯誤處理方式，還有你要寫多少 boilerplate。\u003C\u002Fp>\u003Cp>我自己最常被這件事搞到的是 local dev。module 在某個環境可以跑，換一個環境就失敗，最後才發現是 server 沒有正確送出 content type，導致 streaming instantiate 出問題。很多人會怪 Wasm 不穩，其實只是 dev server 很爛。\u003C\u002Fp>\u003Cp>實作上，我會在 production 先試 \u003Ccode>instantiateStreaming()\u003C\u002Fcode>，如果遇到 MIME 或奇怪環境，再 fallback 到 \u003Ccode>instantiate()\u003C\u002Fcode>。loader 要能明確拋錯，不要把失敗吞掉。模組載不進來，就早點報，不要讓後面才爆炸。\u003C\u002Fp>\u003Cp>如果你要查瀏覽器相容性與行為細節，MDN 的 reference 比你自己猜準很多。要看標準側脈絡，可以順手看 \u003Ca href=\"https:\u002F\u002Fwww.w3.org\u002Fcommunity\u002Fwebassembly\u002F\" rel=\"noopener noreferrer\">W3C WebAssembly Community Group\u003C\u002Fa>。\u003C\u002Fp>\u003Ch2>memory 才是整合最容易翻車的地方\u003C\u002Fh2>\u003Cp>MDN 對 \u003Ccode>WebAssembly.Memory()\u003C\u002Fcode> 的\u003Ca href=\"\u002Fnews\u002Fhow-to-assess-carb-face-beauty-claims-zh\">說法\u003C\u002Fa>很直白：它是可擴充的 \u003Ccode>ArrayBuffer\u003C\u002Fcode>，保存 instance 讀寫的原始 bytes。這段很多人會跳過，然後等到 bug 出現才開始痛。Wasm 不像 JavaScript 那樣直接丟物件給你，它給的是 memory、table、typed boundary。你要知道 bytes 在哪裡、誰擁有、誰負責讀寫。\u003C\u002Fp>\u003Cp>白話一點就是：interop 不是免費的。module 如果期待 buffer，JS 就得提供或讀取；module 如果寫進 memory，JS 就要知道什麼時候去看；如果你在傳字串，就要處理 encoding；如果你在傳陣列，就要尊重 typed view。這些都不是「之後再說」的細節，而是第一天就會踩到的事。\u003C\u002Fp>\u003Cp>我之前接一個 Rust module 到瀏覽器時，數學本身完全沒問題，錯的是邊界。我讀錯了 memory slice，結果看起來像 module 算錯，其實是我自己假設錯。這也是為什麼我一直覺得第一個 integration 要小到不能再小：先讓它只收一個數、吐一個數，先把 runtime 問題切乾淨，再談複雜資料。\u003C\u002Fp>\u003Cp>實操寫法：先定義一份很窄的 memory contract。寫清楚 module 期待什麼、回傳什麼、誰負責 cleanup。只要 export function 會碰 memory，就配一個小 JS helper 來做編碼和解碼。不要讓每個呼叫端都重新猜 ABI。\u003C\u002Fp>\u003Cp>MDN 也有提到 \u003Ccode>WebAssembly.Table()\u003C\u002Fcode> 與 \u003Ccode>WebAssembly.Global()\u003C\u002Fcode>。這兩個你不一定天天用，但一旦碰到 function reference 或 dynamic linking，就真的少不了。平常不用，不代表可以不知道。\u003C\u002Fp>\u003Ch2>text format 不是教科書，是 debug 工具\u003C\u002Fh2>\u003Cp>MDN 有專門講 WebAssembly text format，也有文字轉 binary 的說明。這不是裝飾頁面，這是實戰工具。binary 本來就不好看，text format 則提供你一個人類可讀的方式，讓你去理解 module 到底在幹嘛。\u003C\u002Fp>\u003Cp>也就是說，別期待瀏覽器幫你把 module 的問題講成白話。當東西壞掉時，text format 常常比你一直盯著高階語言 source 更快抓出問題，尤其是 import signature、export 名稱、控制流程這些地方。對學習者來說，它也比直接看 binary 好太多。\u003C\u002Fp>\u003Cp>我以前就碰過一個 compiled module 的行為跟 source 預期不一樣，最後是 function signature mismatch。那種問題用高階語言看半天不一定看得出來，但一旦把 module 結構攤開，答案就很明顯。Wasm 的麻煩是它會很快把錯誤暴露出來；好處也是這樣，至少你不用拖到線上才知道。\u003C\u002Fp>\u003Cp>實操寫法：把 text format 的頁面存成書籤，尤其是你要整合多種語言時。先檢查 module 結構，再去怪 browser。signature 看起來怪、export 對不上、import 找不到，先別亂改 app code，先看 module 本體。\u003C\u002Fp>\u003Cul>\u003Cli>signature 不對時，用 text format。\u003C\u002Fli>\u003Cli>runtime 行為怪時，用 browser devtools。\u003C\u002Fli>\u003Cli>問題還在 Rust、C、C++ 時，回原始語言工具鏈。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>MDN 真正有價值的是路線圖，不是口號\u003C\u002Fh2>\u003Cp>這份 guide 沒有在賣情緒，它是在列東西：概念、從不同語言編譯、載入方式、JavaScript API、reference objects、browser compatibility。這種結構我很買單，因為它跟實際工作順序一樣。先懂模型，再編譯，再載入，再 debug，最後才去看更底層的 reference。\u003C\u002Fp>\u003Cp>翻譯一下就是：MDN 最適合拿來當 workflow map，而不是只拿來背定義。它會告訴你有哪些元件、哪裡會卡、以及你接下來該跳去哪個子頁面。這比很多只會講概念的文章實用太多。\u003C\u002Fp>\u003Cp>我會信這種文件，因為它不假裝難的部分不存在。WebAssembly 的難點本來就不是單一 API，而是工具鏈、memory、載入策略、相容性一起來。MDN 沒把這些藏起來，這也是我一直推薦它的原因。\u003C\u002Fp>\u003Cp>實操寫法：先把 guide 快速掃過一遍，接著直接跳到你 stack 對應的子頁。用 Rust 就看 Rust guide；在瀏覽器載入就看 JS API；在 debug 就看 text format。不要妄想一次把整頁背起來，沒必要。\u003C\u002Fp>\u003Ch2>可抄的模板\u003C\u002Fh2>\u003Cpre>\u003Ccode>\u002F\u002F Minimal browser-side WebAssembly loader pattern\n\u002F\u002F Based on MDN's WebAssembly guide and API reference\n\nexport async function loadWasm(url, imports = {}) {\n  const response = await fetch(url);\n  if (!response.ok) {\n    throw new Error(`Failed to fetch Wasm: ${response.status} ${response.statusText}`);\n  }\n\n  \u002F\u002F Preferred path when the server serves the correct MIME type\n  if (WebAssembly.instantiateStreaming) {\n    try {\n      const { instance, module } = await WebAssembly.instantiateStreaming(response, imports);\n      return { instance, module };\n    } catch (err) {\n      \u002F\u002F Fall back if streaming fails for MIME or environment reasons\n      console.warn(\"instantiateStreaming failed, falling back to ArrayBuffer instantiation\", err);\n    }\n  }\n\n  const bytes = await response.arrayBuffer();\n  const result = await WebAssembly.instantiate(bytes, imports);\n  return {\n    instance: result.instance,\n    module: result.module ?? null,\n  };\n}\n\n\u002F\u002F Example usage\nconst imports = {\n  env: {\n    \u002F\u002F Add host functions here\n    log: (value) => console.log(\"Wasm log:\", value),\n  },\n};\n\nconst { instance } = await loadWasm(\"\u002Fassets\u002Fapp.wasm\", imports);\n\n\u002F\u002F Call exported functions from the module\nif (instance.exports.add) {\n  console.log(\"2 + 3 =\", instance.exports.add(2, 3));\n}\n\n\u002F\u002F Memory helper example\nfunction readString(memory, ptr, len) {\n  const bytes = new Uint8Array(memory.buffer, ptr, len);\n  return new TextDecoder().decode(bytes);\n}\n\nfunction writeString(memory, ptr, text) {\n  const bytes = new TextEncoder().encode(text);\n  new Uint8Array(memory.buffer, ptr, bytes.length).set(bytes);\n  return bytes.length;\n}\n\n\u002F\u002F If your module exports memory, you can use the helpers like this:\n\u002F\u002F const memory = instance.exports.memory;\n\u002F\u002F const message = readString(memory, 0, 12);\n\u002F\u002F const written = writeString(memory, 128, \"hello wasm\");\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>這份模板就是我會直接貼進專案的版本。它先嘗試 streaming，失敗就 fallback，然後把 boundary 留得很明白，不會把整個載入流程包成一坨看不懂的黑盒。\u003C\u002Fp>\u003Cp>如果你的 module 是從 Rust、C 或 C++ 來的，build toolchain 換掉就好，JS wrapper 先別亂動。需要 custom imports 就塞進 \u003Ccode>env\u003C\u002Fcode> 或你 compiler 要的 namespace。需要 memory 存取，就把 helper 跟 loader 放一起，別讓後面的人自己猜 bytes 怎麼跑。\u003C\u002Fp>\u003Cp>我這篇是在拆 MDN 的 \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWebAssembly\" rel=\"noopener noreferrer\">WebAssembly guide\u003C\u002Fa>，上面那份 loader template 是我自己整理出來的可用版本，不是直接抄 MDN 原碼。概念來自文件，包裝方式是我為了日常前端整合重新寫的。\u003C\u002Fp>\u003Cp>另外我也參考了 \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWebAssembly\u002FJavaScript_interface\" rel=\"noopener noreferrer\">MDN JavaScript interface\u003C\u002Fa>、\u003Ca href=\"https:\u002F\u002Fwebassembly.org\u002F\" rel=\"noopener noreferrer\">WebAssembly project\u003C\u002Fa>、以及 \u003Ca href=\"https:\u002F\u002Fwww.w3.org\u002Fcommunity\u002Fwebassembly\u002F\" rel=\"noopener noreferrer\">W3C WebAssembly Community Group\u003C\u002Fa>；原始脈絡是 MDN，模板與解讀是我自己衍生整理的。\u003C\u002Fp>","我把 MDN 的 WebAssembly 指南拆成可直接套用的 JS 載入模式，順手補一份可複製的 Wasm loader 模板。","developer.mozilla.org","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWebAssembly",null,"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1779973422679-zrjy.png","tools","zh","5233cba5-d5cb-4b1d-af8d-b7cc94c85ec0",[17,18,19,20,21],"WebAssembly","MDN","JavaScript","instantiateStreaming","memory",[23,24,25],"Wasm 不是取代 JavaScript，而是讓 JS 當 host、Wasm 當計算模組。","載入策略、memory 邊界、text format 才是整合時真正會踩坑的地方。","先抄 loader 模板，再依你的 Rust\u002FC\u002FC++ toolchain 去換來源，別先做大抽象。",3,"2026-05-28T13:03:09.774221+00:00","2026-05-28T13:03:09.751+00:00","ddbe17bf-4560-43f7-af76-3e7d6e08e601",{"tags":31,"relatedLang":41,"relatedPosts":45},[32,34,36,38,39],{"name":20,"slug":33},"instantiatestreaming",{"name":19,"slug":35},"javascript",{"name":18,"slug":37},"mdn",{"name":21,"slug":21},{"name":17,"slug":40},"webassembly",{"id":15,"slug":42,"title":43,"language":44},"mdn-webassembly-guide-turns-js-into-a-host-en","MDN’s WebAssembly guide turns JS into a host","en",[46,52,58,64,70,76],{"id":47,"slug":48,"title":49,"cover_image":50,"image_url":50,"created_at":51,"category":13},"63d8b456-ad6b-475e-86e9-d4677ca226aa","magenta-realtime-2-score-inside-daw-zh","Magenta RealTime 2 讓你在 DAW 裡即時改曲","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1781046204038-8tox.png","2026-06-09T23:02:55.9651+00:00",{"id":53,"slug":54,"title":55,"cover_image":56,"image_url":56,"created_at":57,"category":13},"f60261ff-a42e-4cfb-9f90-97785e633289","open-source-ai-tools-beat-claude-paid-tiers-zh","開源 AI 工具在價值上已經贏過 Claude 付費方案","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1781045266035-on7t.png","2026-06-09T22:47:20.195939+00:00",{"id":59,"slug":60,"title":61,"cover_image":62,"image_url":62,"created_at":63,"category":13},"8520cd4f-2531-4808-a95d-26f590239d7a","500-ai-agent-projects-show-where-agents-work-now-zh","500 個 AI agent 專案，現在能做什麼","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1781033591132-c0nh.png","2026-06-09T19:32:37.03924+00:00",{"id":65,"slug":66,"title":67,"cover_image":68,"image_url":68,"created_at":69,"category":13},"c557ef1c-7fde-4c86-918e-4fb9680ee9df","chocolatey-go-package-policy-installs-zh","Chocolatey 的 Go 安裝變成政策","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1781029110289-xkbh.png","2026-06-09T18:18:05.078435+00:00",{"id":71,"slug":72,"title":73,"cover_image":74,"image_url":74,"created_at":75,"category":13},"90b2df54-df6e-417d-9e16-91e9ad2f53d7","go-support-policy-turns-releases-into-a-checklist-zh","Go 支援政策把發版變清單","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1781028200122-3m4u.png","2026-06-09T18:02:49.50176+00:00",{"id":77,"slug":78,"title":79,"cover_image":80,"image_url":80,"created_at":81,"category":13},"119c23c6-8ae7-4c4e-820e-1eba0730d702","rustdesk-self-hosting-secure-remote-access-zh","RustDesk 自架遠端存取部署指南","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1781017373324-g7et.png","2026-06-09T15:02:24.118819+00:00",[83,88,93,98,103,108,113,118,123,128],{"id":84,"slug":85,"title":86,"created_at":87},"855cd52f-6fab-46cc-a7c1-42195e8a0de4","surepath-real-time-mcp-policy-controls-zh","SurePath 推出即時 MCP 政策控管","2026-03-26T07:57:40.77233+00:00",{"id":89,"slug":90,"title":91,"created_at":92},"9b19ab54-edef-4dbd-9ce4-a51e4bae4ebb","mcp-in-2026-the-ai-tool-layer-teams-use-zh","2026 年 MCP：團隊真的在用的 AI 工具層","2026-03-26T08:01:46.589694+00:00",{"id":94,"slug":95,"title":96,"created_at":97},"af9c46c3-7a28-410b-9f04-32b3de30a68c","prompting-in-2026-what-actually-works-zh","2026 提示工程，真正有用的是什麼","2026-03-26T08:08:12.453028+00:00",{"id":99,"slug":100,"title":101,"created_at":102},"05553086-6ed0-4758-81fd-6cab24b575e0","garry-tan-open-sources-claude-code-toolkit-zh","Garry Tan 開源 Claude Code 工具包","2026-03-26T08:26:20.068737+00:00",{"id":104,"slug":105,"title":106,"created_at":107},"042a73a2-18a2-433d-9e8f-9802b9559aac","github-ai-projects-to-watch-in-2026-zh","2026 必看 20 個 GitHub AI 專案","2026-03-26T08:28:09.619964+00:00",{"id":109,"slug":110,"title":111,"created_at":112},"a5f94120-ac0d-4483-9a8b-63590071ac6a","claude-code-vs-cursor-2026-zh","Claude Code 與 Cursor 深度對比：202…","2026-03-26T13:27:14.279193+00:00",{"id":114,"slug":115,"title":116,"created_at":117},"0975afa1-e0c7-4130-a20d-d890eaed995e","practical-github-guide-learning-ml-2026-zh","2026 機器學習入門 GitHub 實用指南","2026-03-27T01:16:49.712576+00:00",{"id":119,"slug":120,"title":121,"created_at":122},"bfdb467a-290f-4a80-b3a9-6f081afb6dff","aiml-2026-student-ai-ml-lab-repo-review-zh","AIML-2026：像課綱的學生實驗 Repo","2026-03-27T01:21:51.467798+00:00",{"id":124,"slug":125,"title":126,"created_at":127},"80cabc3e-09fc-4ff5-8f07-b8d68f5ae545","ai-trending-github-repos-and-research-feeds-zh","AI Trending：把 AI 資源收成一張表","2026-03-27T01:31:35.262183+00:00",{"id":129,"slug":130,"title":131,"created_at":132},"3ce6e6e2-bac5-463e-9f8d-45caabcc61f7","awesome-ai-for-science-research-tools-map-zh","AI 科研工具清單，開始像地圖了","2026-03-27T01:46:50.521945+00:00"]