從 MobX 4/5 遷移 {🚀}
MobX 6 與 MobX 5 有很大的不同。此頁面涵蓋了從 MobX 4 和 5 遷移到 6 的指南,以及所有變更的詳細列表。
為了更好地理解,請查看 MobX 6.0 的更新日誌。
⚠️ 警告:根據程式碼庫的大小和複雜性、MobX 使用模式以及自動化測試的品質等因素,本遷移指南可能需要一小時到幾天不等的時間。如果您對持續整合或 QA/測試程序不足以發現任何意外的錯誤,請不要升級。MobX 本身的變更或 Babel/TypeScript 建置設定所需的變更可能會導致意外的行為變更。⚠️
開始使用
- 將 `mobx` 更新到最新版本的 MobX 4/5 並解決任何棄用訊息。
- 將 `mobx` 更新到版本 6。
- 如果您是從 MobX 4 升級,並且需要在沒有 Proxy 的情況下支援 Internet Explorer / React Native,請在應用程式初始化時呼叫 `import { configure } from "mobx"; configure({ useProxies: "never" })`,以退出 Proxy 實作。請查看Proxy 支援章節以了解更多詳細資訊。
- 適用於 Babel 使用者
- 如果您正在使用 Babel 並且啟用了 class-properties,請停用 legacy loose field 支援:`["@babel/plugin-proposal-class-properties", { "loose": false }]`
- (可選)在 MobX 6 中,裝飾器已成為選用功能。如果您不再希望使用裝飾器,請從 Babel 設定和依賴項中移除 `plugin-proposal-decorators`。請查看啟用裝飾器 {🚀}章節以了解更多詳細資訊。
- 適用於 Typescript 使用者
- 將標誌 `"useDefineForClassFields": true` 新增到您的編譯器設定中。
- (可選)在 MobX 6 中,裝飾器已成為選用功能。如果您不再希望使用裝飾器,請從 TypeScript 設定中移除/停用 `experimentalDecorators` 設定。請查看啟用裝飾器 {🚀}章節以了解更多詳細資訊。
- MobX 預設設定已變得更嚴格。建議在完成升級後採用新的預設值,請查看設定 {🚀}章節。在遷移期間,建議以與 v4/v5 開箱即用的相同方式設定 MobX:`import {configure} from "mobx"; configure({ enforceActions: "never" });`。完成整個遷移過程並驗證您的專案按預期工作後,請考慮啟用標誌 `computedRequiresReaction`、`reactionRequiresObservable`、`observableRequiresReaction` 和 `enforceActions: "observed"` 以編寫更符合 MobX 語法的程式碼。
將類別升級為使用 `makeObservable`
由於標準化的 JavaScript 在建構類別欄位方面的限制,MobX 不再能夠透過裝飾器或 `decorate` 工具來改變類別欄位的行為。相反,欄位必須由 `constructor` 設為可觀察的。這可以透過三種不同的方式完成
- 移除所有裝飾器,並在 `constructor` 中呼叫 `makeObservable`,並明確定義哪些欄位應使用哪些裝飾器設為可觀察的。例如:`makeObservable(this, { count: observable, tick: action, elapsedTime: computed })`(請注意,第二個參數對應於傳遞給 `decorate` 的內容)。如果您想在程式碼庫中捨棄裝飾器,並且專案還不太大,建議使用這種方法。
- 保留所有裝飾器,並在 `constructor` 中呼叫 `makeObservable(this)`。這將讀取裝飾器產生的中繼資料。如果您想限制 MobX 6 遷移的影響,建議使用這種方法。
- 移除裝飾器,並在類別 `constructor` 中使用 `makeAutoObservable(this)`。
查看makeObservable / makeAutoObservable以了解更多詳細資訊。
一些需要注意的細節
- 在每個宣告基於 MobX 成員的類別定義中,都需要使用 `makeObservable` / `makeAutoObservable`。因此,如果子類別和超類別都引入了可觀察成員,則它們都需要呼叫 `makeObservable`。
- `makeAutoObservable` 將使用新的裝飾器`autoAction`標記方法,該裝飾器僅在非衍生環境中套用 `action`。這使得從計算屬性中呼叫自動裝飾的方法也變得安全。
遷移具有大量類別的大型程式碼庫可能會令人生畏。但別擔心,有一個程式碼修改器可以自動化上述過程!!
使用 `mobx-undecorate` codemod 升級你的程式碼
如果您是現有的 MobX 使用者,您的程式碼中會使用大量的裝飾器,或者等效地呼叫 `decorate`。
`mobx-undecorate`套件提供了一個 codemod,可以自動將你的程式碼更新為符合 MobX 6 的規範。不需要安裝它;你可以使用`npx`工具下載並執行它,如果你還沒有安裝 `npx` 的話,則需要安裝它。
要擺脫所有 MobX 裝飾器的使用,並將它們替換為等效的 `makeObservable` 呼叫,請轉到包含你的原始碼的目錄並執行
npx mobx-undecorate
`npx mobx-undecorate your-project-directory`
npx mobx-undecorate --keepDecorators
MobX 將繼續支援裝飾器--所以如果你想保留它們,並且只在需要的地方引入 `makeObservable(this)`,你可以使用 `--keepDecorators` 選項
`npx mobx-undecorate your-project-directory --keepDecorators`
請參閱文件以了解更多選項。
`mobx-undecorate` 的限制
`mobx-undecorate` 命令必須在尚未具有建構函式的類別中引入建構函式。如果建構函式的基類需要參數,則 codemod 無法為正在升級的子類別引入這些參數,並且 `super` 呼叫也不會傳遞它們。你必須手動修復這些問題。該工具將在這些情況下產生 `// TODO: [mobx-undecorate]` 註釋。
成為深度可觀察結構一部分的函數會自動轉換為 autoAction
,如果是 generator 函數則會轉換為 flow
。詳情請參閱 推斷規則。這表示原始函數參考不會被保留 - 與陣列/物件/集合/映射轉換為可觀察物件時原始參考會遺失的原理相同。在某些情況下,這可能會令人感到意外。如果不希望出現這種行為,請使用 observable.shallow
/ observable.ref
/ false
/ deep: false
來防止轉換過程,或確保函數已為 action
,如 issue 中所示。