[Capacitor] 從 Cordova app 轉移到 Capacitor
用 Cordova 來寫 app 已經有五年了 (雖然目前也只寫了一個 圖書館多重登入 app…)
近年來遇到不少問題,像是 CORS 的限制,
導致以 Web app 為底的 Cordova app 發出的 HTTP 請求被 CORS 擋掉。
然後像是 Cookie 的 Same site 限制,
從 Cordova app 發出的 HTTP 請求也被認為非同源,然後拿不到 Cookie…
另一個問題,是 Cordova 的更新速度明顯的變慢了,
查了一下似乎是因為母公司 Adobe 已經不再維護,就只剩社群支撐。
另外,Cordova 的使用人數越來越少,
也導致遇到問題時,想要找解決方案時,常常找不太到…
在找解決方案時,意外看到一個叫 Capacitor 的東西,
這是出 Ionic 框架的公司出的,似乎原本他們也是用 Cordova,
後來將 Runtime 從 Cordova 換成他們自己開發的 Capacitor,
方便他們遇到問題時就可以即時修正~
看了一下,想說就來試試換成 Capacitor 看看,
反正 Cordova 看來也邁入老年期了,
換成一個還有在維護的專案可能還是會好一些~
Capacitor 支援 Cordova to Capacitor Migration,
所以可以方便的從現有的 Cordova app 轉換過去,
不過當然不太可能功能完全正常移轉…
嘗試了之後,我覺得比較好的方法如下~
1. 將專案複製到另一個目錄
畢竟這是一個很大的改變,把東西複製到一個新的目錄,
再開始改吧,這樣至少還有舊的目錄可以參考,
失敗時也可以立刻重新開始~
2. 移除所有的 Cordova plugin
其實 Capacitor 它會自動偵測舊的 plugin 是否仍能使用,
不相容的 plugin 就會略過的樣子 (不知道如何判斷的)。
不過因為 Capacitor 自己也提供了一些可取代 plugin 的功能,
混在一起的話,感覺不太容易分辨。
所以我自己的作法是移除掉所有的 Cordova plugin,
再來開始遷移的過程,這樣只要哪裡運作不正確,
就直接查看是缺什麼再補就好,
這樣可能會比新舊混在一起,不知道是哪邊的問題要好~
先執行 cordova plugin
看看有哪些 plugin:
$ cordova plugin admob-plus-cordova 2.0.0-alpha.13 "admob-plus-cordova" cordova-plugin-cors 1.3.0 "CORS" cordova-plugin-dialogs 2.0.2 "Notification" cordova-plugin-extension 1.6.0 "Cordova Plugin Extension" cordova-plugin-file 8.0.0 "File" cordova-plugin-idfa 2.1.0 "cordova-plugin-idfa" cordova-plugin-inappbrowser 5.0.0 "InAppBrowser" cordova-plugin-statusbar 3.0.0 "StatusBar" cordova-promise-polyfill 0.0.2 "cordova-promise-polyfill" cordova-support-android-plugin 2.0.4 "cordova-support-android-plugin"
再來就是將 plugin 一個個移掉…
有時 plugin 之間會有相依性而移除失敗,
這時就先移掉沒有被其他人依賴的 plugin 就好:
cordova plugin rm admob-plus-cordova cordova plugin rm cordova-plugin-cors ......
3. 安裝 Capacitor
在新的 Cordova 專案目錄下,執行下面指令安裝 Capacitor:
npm i @capacitor/core npm i -D @capacitor/cli
4. 初始化 Capacitor 設定檔
接著是執行 npx cap init
,
這會建立一個 Capacitor 用的設定檔 capacitor.config.json。
首先給它 App 的名稱:
$ npx cap init [?] What is the name of your app? This should be a human-friendly app name, like what you'd see in the App Store. ✔ Name … Library Multi-Login
Package ID 這邊就給之前 App 的 ID,通常是 domain name 的反轉,
像我的 app 就是 idv.ephrain.multilibrarylogin:
[?] What should be the Package ID for your app? Package IDs (aka Bundle ID in iOS and Application ID in Android) are unique identifiers for apps. They must be in reverse domain name notation, generally representing a domain name that you or your company owns. ✔ Package ID … idv.ephrain.multilibrarylogin
接著指定放置 Web app 資源 (html, css, js) 的目錄,預設是 www。
要注意的是這目錄下要有個 index.html 作為入口。
我之前的 app 入口是 www/popup.html,因此得把它改名成 index.html,
同時把程式裡參考到 popup.html 的部分都改成 index.html:
[?] What is the web asset directory for your app? This directory should contain the final index.html of your app. ✔ Web asset directory … www
接著詢問是否要把 Cordova 的設定檔轉移進來,自然是選擇 Yes 囉:
[?] Cordova preferences can be automatically ported to capacitor.config.json. Keep in mind: Not all values can be automatically migrated from config.xml. There may be more work to do. More info: https://capacitorjs.com/docs/cordova/migrating-from-cordova-to-capacitor ✔ Migrate Cordova preferences from config.xml? … yes ✔ Creating capacitor.config.json in /Users/testuser/MultiLibraryLogin in 3.63ms [success] capacitor.config.json created!
剩下加入 Ionic 社群、與傳送使用資料等等,就自行選擇吧:
Next steps: https://capacitorjs.com/docs/getting-started#where-to-go-next [?] Join the Ionic Community! 💙 Connect with millions of developers on the Ionic Forum and get access to live events, news updates, and more. ✔ Create free Ionic account? … yes [?] Would you like to help improve Capacitor by sharing anonymous usage data? 💖 Read more about what is being collected and why here: https://capacitorjs.com/telemetry. You can change your mind at any time by using the npx cap telemetry command. ✔ Share anonymous usage data? … yes Thank you for helping to make Capacitor better! 💖 Information about the data we collect is available on our website: https://capacitorjs.com/telemetry
5. 安裝 Android 與 iOS 平台
接著執行下面指令,
來安裝 Capacitor 在 Android 與 iOS 平台的支援:
npm i @capacitor/android @capacitor/ios
接著建立專案中給 Android 和 iOS 使用的 native code 的部分:
npx cap add android npx cap add ios
6. 在 iOS Simulator 中執行專案
為了測試專案是否有轉移成功,我先試 iOS 版本能不能執行
(只先看能不能跑,至於跑起來是否有錯誤,就是之後的事了)
我們可以執行 npx cap run ios
,這會讓你選擇要執行的 iOS simulator,
選好後就會自動編譯並在模擬器中把 app 跑起來:
$ npx cap run ios ✔ Copying web assets from www to ios/App/App/public in 310.24ms ✔ Creating capacitor.config.json in ios/App/App in 6.50ms [info] Inlining sourcemaps ✔ copy ios in 361.27ms ✔ Updating iOS plugins in 2.79ms ✔ Updating iOS native dependencies with pod install in 7.45s ✔ update ios in 7.65s ✔ Please choose a target device: › iPhone 12 Pro (iOS 14.3) (simulator) (B3CCF3F5-EF2D-4F28-BC7F-B5B94D4A5953) ✔ Running xcodebuild in 55.40s ✔ Deploying App.app to B3CCF3F5-EF2D-4F28-BC7F-B5B94D4A5953 in 5.30s
跑起來的樣子:
不過每次都要選擇模擬器有點麻煩,
所以可以先查詢一下模擬器的 ID:
$ npx cap run ios --list Name API Target ID --------------------------------------------------------------------------------------------------- iPad (10th generation) (simulator) iOS 17.0 701CE542-68B6-4418-A80D-3F7348ED1E37 iPad Air (5th generation) (simulator) iOS 17.0 503335B6-45DA-4B93-A06D-9485D404AD27 iPad Pro (11-inch) (4th generation) (simulator) iOS 17.0 9FEE47CC-97BD-4ADA-9AE0-AFE0CA020C10 iPad Pro (12.9-inch) (6th generation) (simulator) iOS 17.0 65C931D3-9060-49D6-8591-74E2FA4AA801 iPad mini (6th generation) (simulator) iOS 17.0 89272DB0-04A1-4BC5-8AFA-DE8730A28588 iPhone 12 Pro (iOS 14.3) (simulator) iOS 14.3 B3CCF3F5-EF2D-4F28-BC7F-B5B94D4A5953 iPhone 15 (simulator) iOS 17.0 4C27CBAA-4695-412D-9CB7-10CA316EA694 iPhone 15 Plus (simulator) iOS 17.0 AC6A7EB7-3F38-4899-B0E6-83842064844C iPhone 15 Pro (simulator) iOS 17.0 A00EFB10-C0D9-4402-80FD-C2B424750D7E iPhone 15 Pro Max (simulator) iOS 17.0 3079DBF0-4BBA-47FE-9D50-0ED3D2136FFB iPhone SE (3rd generation) (simulator) iOS 17.0 1EAA5B43-E1C5-45B5-BA5A-E1A2833908F3
然後在執行時直接指定模擬器 ID,就可以直接跑起來了:
npx cap run ios --target B3CCF3F5-EF2D-4F28-BC7F-B5B94D4A5953
以上就是將 Cordova app 轉移到 Capacitor 的過程,
當然目前其實 app 的功能還是有問題的,
接下來就得依照 Capacitor 的方式一步步解決囉~