與 ChatGPT 協作,升級 Flutter 1.22.6 直衝 Flutter 最新版
前言
我在多年以前用 Flutter 幫客戶開發一款 App,因後來沒有額外的需求,所以 Flutter 的版本就停在 Flutter 1.22.6 直到現在。
Google Play Console 去年通知我需要將 Android 指定為 Android 14 或以上版本,但是我都沒有理它。
今年它對我下了最後通牒,若我在期限內未更新,就要把我的 App 下架,這使我慌了手腳。
因我原本的compileSdkVersion
為 33,原本想說只要將 compileSdkVersion 升級成 34 即可,殊不知,遇到了問題,事情不是我想的那麼簡單。
升級 compileSdkVersion
時,需要考慮 AGP (Android Gradle plugin) 的版本,
官方文件說明,AGP 最低版本需要為 8.1.1 才能使用 API 34,而需要使用 AGP 8.1.1,Gradle 需要升級至 8.0。(而當時我的 Gradle 版本為 6.0)
而 Gradle 的升級會連帶影響 build.gradle
的內容也需要修改。搭配 AI 作為升級幫手,我可以更快速的改寫 build.gradle
成為符合 Gradle 8 的格式。
與 AI 的合作
像這樣大版本的升級,總是令人心驚膽跳,而我之前其實也有嘗試升級過(看著 branch upgrade_flutter_2),但是最後就不了了之。
這幾年 AI 進步神速,大家都有目共睹,尤其作為開發者的助手協助解決各式各樣問題,更是讓所有開發者趨之若鶩。我心想,這次就與 AI 一起搭配,一定比我單打獨鬥更快,更何況這也是一個很久的專案,不打算花太久處理。
在開始之前,首先盤點一下可能會處理的項目
升級 Flutter 版本
如前文所述,需要升級 compileSdkVersion 至 34,而連帶影響 gradle、AGP 都需要一併升級,當然 Flutter 的版本也需要升級,而一開始我的打算是升級到一個剛剛好的版本即可(後來發現,這樣反而更痛苦)
升級套件
升級 Flutter 版本,意味著需要升級套件,針對選定的 Flutter 版本需要選擇適當的版本,而升級套件後,有些套件也經歷了重大修改,所以也導致原本使用的地方也需要同步調整。另一個棘手的問題是,某些套件沒有繼續維護,此時就需要考慮如何使用替代的套件。
處理 Null safety
Flutter 2 迎來了 Null safety,在這版之後,型別就有分為可空(Nullable)與不可空(non-nullable)型別。當從舊版本升級後,該選可空或不可空,就需要好好考慮。
開始升級
在開始之前,讓自己免於`版本地獄`中,所以我們使用 FVM 管理 Flutter 版本,並使用 SDKMAN 控制 Java 版本,如此我們就能夠快速的切換 Flutter 及 Java 版本。
因為我不想要升到最新版本,於是我打算生一個大版本即可,也就是 Flutter 2。AI 的回覆如同前面所分析的一樣,它告知我需要升級套件,如下圖第三點。
將套件版本升至 AI 所建議的版本後,發現還是有問題。
Running "flutter pub get" in _app…
Because json_serializable >=3.5.0 <4.0.0-nullsafety.0 depends on json_annotation >=3.1.0 ❤.2.0 and kinmen_monitor_app depends on json_annotation ^4.6.0, json_serializable >=3.5.0 <4.0.0-nullsafety.0 is forbidden.
So, because kinmen_monitor_app depends on json_serializable ^3.5.1, version solving failed.
pub get failed (1; So, because kinmen_monitor_app depends on json_serializable ^3.5.1, version solving failed.)
開始升級套件,就會遇到套件版本與 Flutter 版本不符合、與其他套件的版本衝突等問題,遇到這些問題時,如果每次都將問題直接丟給 AI 來解答,十之八九就是一直換套件的版本。
也就是說,遇到套件升級地獄,就是一直把錯誤的地方餵給 AI ,讓它幫你找出要調整哪一個套件版本。
一口氣升級至 Flutter 3.29.2
原本我只打算升級到 Flutter 2,但很快發現這是不現實的。因為我需要使用新版的 Firebase SDK、新版套件、甚至 Xcode / Android Studio 的基本版本,都已不再支援 Flutter 2。
例如 syncfusion_flutter_charts
是一款用來繪製圖表的套件,在該套件的新版本就必須要升級到 Flutter 3 以上。
與其這樣的將套件一點一點的升上去,還不如直接將 Flutter 升至最新版,接著將所有的套件也一併升至最新版,來減少升版地獄。
如前文所述,在升級套件時,有遇到套件已無維護的問題,如 liquid_progress_indicator
,幸運的是,我找到有 v2 版本可以使用,於是我就直接詢問 AI 該如何替換。
經過一番奮鬥後,我的程式碼總算沒有 build failure 了。
Null-Safety
前文提到,因為 Flutter 2 引入了 Null Safety,所以型別分為可空與不可空,我在一開始都是設定為不可空,雖然可以編譯成功,但是進入 App 後,就會出現錯誤。
請 AI 幫忙後,就可以幫忙解決。
而像是 Data Model,可能會因為使用不可空的型別,造成打 API 後得到 null,進而引發系統錯誤。所以這個地方也需要多加注意。
不過,雖然將原本的程式碼改為一律改為可空型別就可以解決,但我們還是要考慮是不是要使用不可空型別。這個部分就需要對你的程式多一點了解。
修改升級套件的使用方法
除了可空、不可空的問題外,當升級套件的版本後,隨之而來的問題就是,有可能使用的方式改變了,而我在這邊遇到最大的問題就是 Bloc 的使用錯誤。
如 Bloc 的例子,舊版的 Bloc 是需要在 Bloc 類別中,在抽象函式 mapEventToState()
函式裡,針對收到的事件來作處理;反之,新版的 Bloc 是利用 on<Event>()
的方式註冊每一個 handler,如此每個事件就會有一個獨立的方法來處理,而不會集中在一個函式。
而透過 AI,每一個 Bloc 的類別都能夠快速修改。
使用 AI 升級 Flutter 版本心得
先說優點,一開始很不想要升級,因為最新的版本與專案使用的版本已經相距太遠,所以對我來說要怎麼修改,也是一個頭兩個大。這次發現 ChatGPT 能夠搭配 IDE 一起使用。這能提升我們的效率,而且在修改的時候,也會告訴我們前因後果,以及考慮的地方。而現在的版本,它們的回答相當口語化,感覺就是一個 Z 世代的年輕人在跟你對話。而最後也比我預期的時間還要快就把問題解決。
缺點呢?不得不說,他有時候會卡在一些奇怪的地方,譬如說會很執著要使用某些特殊的套件版本,當這個版本不行時,可能又會提供另一個套件的版本出來,如此就會花費很多時間在測試這些版本是否正確。就從結果來看,應該直接將 Flutter 升級至最新的版本,一來是,我們可以把套件升到最新,淘汰舊的套件,二來是,我們就可以一勞永逸,避免近期內又需要在做同樣的動作。
另外就是,在 ChatGPT 來說,它與 IDE 的協作只能觀看一兩個檔案,就是我們點開的檔案,但是程式碼的 context 可能是需要能夠看整個專案才有辦法了解。所以在有限的資訊下,它很有可能就會給出錯誤的答案。
近期,Vibe Coding 的話題火熱,基本上已經呈現兩個派系,支持與不支持。支持的人會說,可以快速的產出程式碼,減少開發時間;不支持的人會說,它讓程式碼更難維護,比寫爛的程式碼還更恐怖。但我是認為,對於我們熟悉的語言,我們使用 AI 提出的建議之前,應該要有能力辨別是否正確,當「你」使用 AI 的程式碼後,就是你上的 code,不是 ChatGPT,所以要拿去當你的工作成果,你需要有能力檢視其成果是否如預期。
當然,面對你不熟悉的程式語言,搭配 AI 可以加速從 0 到 1 的過程,可以快速驗證想法是否正確,至於創造出來後,後續的修改,還是自己要有一點開發的能力,才有辦法持續修改下去,你才知道該下什麼 Prompt 給 AI。
「將 AI 作為 Pair Programming 的夥伴吧!」
這篇文章我花了兩個禮拜 😜,
喜歡我文章的朋友,別忘了給我拍手👏🏻鼓勵