Skip to main content

【CapacitorJS】I come back

· 3 min read

剛接觸前端時就玩過 CapacitorJS,當時因故產品沒有上線。時隔約 5 年又有機會重拾這個工具,趁有更多經驗時記錄一下:它如何把 website 變成 app。

CapacitorJS 的定位

Capacitor 是跨平台的原生橋接層(Native Bridge),核心想法是:

「Web 技術(HTML、CSS、JS/TS)+ 原生容器(iOS/Android Shell)= App」

因此你寫的網頁程式(React、Vue、Angular、Svelte 等)會跑在原生 WebView 裡,並透過 Capacitor 提供的 API 呼叫原生功能

打包成 App 的原理

iOS

  • Capacitor 會在專案裡建立一個 Xcode Project
  • 專案內使用 WKWebView(蘋果的高效能 WebView)。
  • Web App 建置後的檔案(index.html + JS/CSS)會放進 iOS App 的 www 資料夾。
  • App 啟動時即為原生 App + WKWebView 載入前端頁面
  • Capacitor iOS Plugin(Swift/Objective-C)負責橋接,例如藍牙、相機、檔案系統等。

Android

  • Capacitor 會建立 Android Studio 專案
  • 使用 WebView(Chromium-based)。
  • 同樣把 Web App 編譯產物放到 assets/www,由 WebView 載入。
  • 原生功能(Camera、Bluetooth、Push Notification 等)透過 Capacitor Plugin(Java/Kotlin)呼叫。

JS 和 Native 溝通機制

這是 Capacitor 最核心的部分:

  • JS → Native:例如呼叫 Capacitor.Plugins.Camera.getPhoto() → JS 透過 bridge 把指令送到原生層 → 原生相機開啟 → 拍完後結果回傳 JS。
  • Native → JS:原生事件(例如 push notification)透過 bridge 回傳到 JS,觸發 callback。

溝通底層依賴 WebView 的 message passing(Android 用 postMessage,iOS 用 WKScriptMessageHandler),再加上 Capacitor 自己的序列化格式。

小結

CapacitorJS 把 Web 變成 App 的方式:用原生 App 容器裝一個 WebView,載入你的 Web App,並透過 Plugin 系統讓 JS 能呼叫原生 API。

為什麼會用到 Ruby?

在 iOS 開發環境中,Ruby 會間接成為必要依賴,原因如下。

CocoaPods 的依賴

  • CocoaPods 是 iOS 的套件管理器:Capacitor 建置 iOS 時會用它來管理原生依賴(插件、原生模組),負責下載、整合與配置第三方庫,讓 Web 程式碼能橋接到 iOS 原生 API(相機、檔案系統等)。

  • Ruby 是 CocoaPods 的運行基礎:CocoaPods 用 Ruby 撰寫,透過 gem 安裝與執行。安裝指令為:

    sudo gem install cocoapods

    會使用系統的 Ruby 環境。

  • Capacitor iOS 建置流程:執行下列指令時,

    npx cap sync
    # or
    npx cap run ios

    Capacitor 會自動呼叫 CocoaPods 更新 iOS 專案的 Podfile 與依賴。若沒有 Ruby 與 CocoaPods,建置會失敗,出現如「CocoaPods not installed」或「Pod install failed」等錯誤。

若使用例如 @capacitor-firebase/authentication 這類 package,應在 Podfile 中看到對應的 pod,例如:

def capacitor_pods
# ...
pod 'CapacitorFirebaseAuthentication', :path => '../../node_modules/@capacitor-firebase/authentication'
# ...
end

否則 iOS App 無法辨識該 package,功能無法使用。

此外,部分功能需要在 Info.plist(iOS)或 AndroidManifest.xml(Android)中開啟對應權限,才能正常使用。

到目前的開發體驗

整體還算可以;在現有 AI 輔助下能彌補部分文件不清楚的地方,許多細節仍是和 AI 一起摸索出來的。