跳至主要內容
YIP NEWS
YIP NEWS

10月7日

備料臺不能再偷拿爐臺上的東西了:KMP 這次改的規矩,廚房裡早就有

生活爐 美食生活

JetBrains 替 KMP 編譯流程加入 Separate Compilation,禁止 commonMain 的依賴穿透,我們把這則工程消息翻譯成廚房裡備料區與爐臺各自分工的滋味故事。

刊出 (台北時間) 閱讀約 4 分鐘

廚房裡有一條不成文的規矩:備料的歸備料,開火的歸開火。切蔥的砧板上不該出現剛起鍋的油湯,涼拌的小黃瓜也不該順手淋到還在滾的高湯裡。2026 年 10 月 3 日,開發者「戀貓de小郭」在掘金上分享了一則工程圈的消息:JetBrains 又調整了 KMP 的編譯流程,新的 Separate Compilation 機制,禁止了 commonMain 的依賴穿透。這句話聽起來離餐桌很遠,但你若在自家廚房做過一桌菜,會發現它說的其實是同一件事:每個區域只看自己的東西,界線清楚,菜才不會在最後一刻走味。

先說清楚原本發生了什麼。KMP 是一套跨平臺的開發方式,同一段共用程式碼(commonMain)最後要能變成不同平臺的成品。過去的問題在於,寫程式的人眼前看到的規則,和實際編譯時的規則,居然可以不一樣。同一行程式碼,IDE 標紅說這個東西不存在,Gradle 卻順利編過去了;你以為自己寫的是大家都能用的共用邏輯,實際上它偷偷用到了某個平臺才有的實作,等換到另一個平臺,問題才一次爆開。

放到廚房裡,這就像你在備料臺切一盤要給全桌共享的涼菜,切著切著,順手把只有這一桌才有的那罐辣椒醬挖了一勺進去。在這一桌喫,沒人發現,甚至覺得夠味。可這盤菜的定位是「大家都 能喫的共用菜」,哪天端去別桌,那罐辣椒醬不在了,整盤菜當場失信於人。IDE 是那個站在備料臺旁、只看食譜上「共用」兩個字的人,所以它告訴你不行;舊的編譯流程則像那個已經聞到醬香、覺得能喫就端上桌的人。兩邊都沒惡意,但兩邊說的話對不上,桌邊的人就一臉困惑。

來源文章裡給了一個具體的例子。某個函式庫只發布了 JVM 平臺的程式碼,照理說共用的 commonMain 不該看見它。但過去 JVM 平臺編譯時,共用的原始碼會和平臺原始碼一起面對平臺的產物,那個類別剛好就在裡面,於是編譯器覺得合法,紅字就這麼被繞過去了。commonTest 也有同樣的毛病:你以為自己寫的是通用測試,其實它早就倚賴了某個平臺的實作,換個平臺才現出原形。

這和老闆說要重新裝修廚房、而鍋裡的湯還在滾的道理相近,流程一改,最先有感覺的永遠是現場那雙手。

Separate Compilation 做的事,說穿了就是把那條界線重新畫清楚。commonMain 在分析時,只能看屬於自己的 metadata KLIB,也就是「公共世界有哪些宣告」的那份清單;平臺的 .jar 和平臺 KLIB 還在,後續的平臺編譯也照用,但它們不能再偷偷參與共用程式碼的判斷。真的需要跨過去,就得用 expect/actual 這種明確的方式,把公共的宣告和平臺的實作好好接起來。

對應到做菜,這就是回到基本功:共用的醬底就寫在共用的食譜卡上,哪一味要因地制宜,另外開一張平臺專屬的卡,標清楚哪個爐、哪桌用。聽起來囉嗦,實際上省掉的是那種「這盤為什麼在阿嬤家好喫、端來臺北就走味」的羅生門。界線畫清楚的食譜,誰接手都能重現同一個味道。

如果你身邊有寫程式的家人,這兩天他若盯著螢幕皺眉,嘴裡唸著什麼依賴穿透,別急著催他上桌。你只要說一句:備料臺不能偷拿爐臺上的東西,這規矩廚房一直都有。他大概會愣三秒,然後笑了。飯菜趁熱,規矩也是。

熱點話題

KMP 又改了編譯流程, Separate Compilation 禁止了 commonMain 的依賴穿透 (原始來源:https://juejin.cn/post/7691872111024586752)