精選文章
- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
把 Kotlin Wasm / JS 專案佈署到 GitHub.io
用 Compose Multiplatform 或 Kotlin/Wasm 寫好網頁版之後,最直覺的公開方式就是放到 GitHub Pages。網址會是 https://你的帳號.github.io,免費、HTTPS 現成,也適合當作品展示。
這篇整理實務流程:先用 Gradle 打出發行包,再把 dist 裡的靜態檔拷到 github.io 倉庫。
先搞清楚兩種站
GitHub Pages 常見有兩種位置,拷檔前先決定要用哪一種。
個人首頁站
倉庫名稱必須剛好是 帳號.github.io。
網址:https://帳號.github.io/
檔案放倉庫根目錄,瀏覽器會直接讀 index.html。
專案站
倉庫可以叫任何名字,例如 my-wasm-app。
網址:https://帳號.github.io/my-wasm-app/
檔案一樣可放根目錄,或放 docs/,再到 Settings → Pages 指定來源。
後面範例以「獨立的 帳號.github.io 倉庫」為主,也就是很多人說的「拷到 github.io repo」。
第一步:打 production 發行包
在專案根目錄執行(有 gradlew 的那層):
./gradlew wasmJsBrowserDistribution若模組名稱是 KMP Wizard 預設的 composeApp:
./gradlew :composeApp:wasmJsBrowserDistribution目標是 Kotlin/JS、不是 Wasm 時:
./gradlew jsBrowserDistribution
# 或
./gradlew :composeApp:jsBrowserDistribution重點是任務名稱裡的 BrowserDistribution。它會把 HTML、JS、WASM、圖片與 composeResources 一次打包成可直接給瀏覽器讀的靜態網站。
這幾個不要搞混:
| 任務 | 用途 |
|---|---|
| wasmJsBrowserDevelopmentRun | 本機開發預覽 |
| wasmJsBrowserProductionRun | 本機用 production 設定預覽 |
| wasmJsBrowserProductionWebpack | 多半只有 webpack 產物,資源常要自己補 |
| wasmJsBrowserDistribution | 要上傳 GitHub Pages 用這個 |
官方教學也是跑 wasmJsBrowserDistribution,再到發行目錄拿檔案去佈署。
第二步:找到真正要上傳的資料夾
產物不是專案根目錄下隨便一個叫 dist 的資料夾,而是模組 build 裡面這層:
composeApp/build/dist/wasmJs/productionExecutable/常見對照:
| 目標 | 目錄 |
|---|---|
| Kotlin/Wasm | composeApp/build/dist/wasmJs/productionExecutable/ |
| Kotlin/JS | composeApp/build/dist/js/productionExecutable/ |
| 模組叫 webApp | webApp/build/dist/wasmJs/productionExecutable/ |
打開後通常會看到:
- index.html
- *.js
- *.wasm
- 資源目錄(例如 composeResources)
拷這個資料夾的內容,不要整份 build/ 丟上去。build/ 裡還有快取、中間檔,又大又沒必要公開。
第三步:拷進 github.io 倉庫
假設目錄長這樣:
~/code/
my-kmp-app/ ← 原始專案(跑 gradlew 的地方)
yourname.github.io/ ← Pages 專用倉庫在原始專案打完包之後:
# 建議用 rsync:同步且可刪掉舊產物,但不會動到目的地的 .git
rsync -av --delete \
composeApp/build/dist/wasmJs/productionExecutable/ \
../yourname.github.io/沒有 rsync 也可以:
cp -R composeApp/build/dist/wasmJs/productionExecutable/. ../yourname.github.io/注意結尾的 /.:拷的是「資料夾裡的檔案」,不是再套一層 productionExecutable。GitHub Pages 根目錄必須直接看得到 index.html。
用 rsync --delete 前先確認目的地路徑沒寫錯。它會刪掉目的地裡「發行包沒有的檔案」,但應保留 .git。CNAME、自訂 README.md 若不想被刪,就不要加 --delete,或把這些檔另外備份。
第四步:提交並打開 Pages
進 github.io 倉庫:
cd ../yourname.github.io
git add -A
git commit -m "Update wasm/js build"
git push第一次佈署時,到該倉庫:
- Settings → Pages
- Source 選 Deploy from a branch
- Branch 選 main(或你實際推送的分支)
- Folder 選 / (root)
- Save
等一兩分鐘,打開:
https://yourname.github.io/若是專案站,網址會多一層倉庫名:
https://yourname.github.io/my-wasm-app/專案站特別注意:路徑不是根目錄
個人站 帳號.github.io 的資源路徑是 /xxx.js。
專案站卻是 /倉庫名/xxx.js。
如果 index.html 寫死從網站根目錄載入 JS / WASM,專案站會 404、畫面空白。處理方式:
- 儘量用相對路徑(./composeApp.js),不要寫成 /composeApp.js
- 或在 index.html 加正確的 base,例如:
<base href="/my-wasm-app/">本機用 file:// 開 index.html 通常也不行,Wasm 需要透過 HTTP 提供。要預覽請用 Gradle 的 *Run 任務,或任意靜態伺服器指到 productionExecutable。
瀏覽器與 GitHub Pages 的限制
Kotlin/Wasm 需要較新的瀏覽器(例如 Chrome 119+),因為依賴 WasmGC。
另外,若應用用到 SharedArrayBuffer 或 Wasm threads,伺服器需要這兩個 HTTP header:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corpGitHub Pages 本身不能自訂這些 header。 多數 Compose for Web 展示站仍可直接放上 github.io;若執行期明確要求 cross-origin isolation,可考慮:
- 在頁面加 coi-serviceworker 這類 service worker 補 header
- 或改放到能設 _headers 的平台(例如 Cloudflare Pages)
第一次打開後若白畫面,先開開發者工具看 Console / Network:是 .wasm 404、路徑錯,還是瀏覽器太舊,通常一眼能分出來。
建議的更新節奏
之後每次要更新網站,固定三步就好:
# 1. 在原始專案重建
./gradlew :composeApp:wasmJsBrowserDistribution
# 2. 同步產物到 Pages 倉庫
rsync -av --delete \
composeApp/build/dist/wasmJs/productionExecutable/ \
../yourname.github.io/
# 3. 推送
cd ../yourname.github.io
git add -A && git commit -m "Update site" && git push想省手動拷檔,也可以之後再加 GitHub Actions:在原始專案 CI 裡跑同一個 Gradle 任務,把 productionExecutable 發到 Pages。手動流程搞懂後,自動化只是把這三步搬到雲端。
快速檢查清單
- 跑的是 wasmJsBrowserDistribution 或 jsBrowserDistribution,不是 *Run
- 拷的是 build/dist/.../productionExecutable/ 的內容
- github.io 根目錄有 index.html
- Pages 已指定正確分支與 / (root)(或 docs/)
- 專案站的資源路徑有考慮子路徑
- 用支援 WasmGC 的瀏覽器測試
一句話記住:Gradle 負責產出可上線的靜態檔,GitHub.io 只負責托管這些檔。 中間那次 copy,就是把程式從開發專案交到公開網站的那一步。
留言
張貼留言