一、metro 的快取機制
1、為什麼要快取
react-native 在執行 react-native start 或者 react-native bundle 命令的時候,都會有快取。
目的其實很簡單,metro 在打包的時候需要將 TS 和 ES6/7 的程式碼轉換為 ES5 的目的碼。
那如果一個檔案沒有任何變更,這個時候我們就不需要去轉換它了,所以 metro 設定了一套檔案快取機制來最佳化編譯轉換速度 。
2、兩種快取機制
metro 的快取實現在 node_modules/metro-cache 中,主要有兩種快取機制:
服務端快取:HttpStore
本地快取:FileStore
服務端主要是透過伺服器來快取相關內容,優勢是不用擔心快取的大小和時間限制,可以靈活的設定快取策略,不過這個我們目前沒有使用到,後期可以考慮。
metro 預設的快取機制是 FileStore,這也是我們目前使用的快取機制,FileStore 實際上就是將編譯轉換後的檔案快取起來,以便下一次編譯的時候能夠避免重複轉換,加快編譯速度。
3、FileStore 快取原理
FileStore 快取的原理其實很簡單:
快取的key:表名 + 檔案內容對映生成的 hash 值
快取的內容:轉換後的檔案內容
當執行轉換的時候,如果發現檔案的 hash 值存在,那麼就說明檔案內容沒有發生變化,就不會去執行轉換操作, 大大節省了編譯時間。FileStore 為了避免 hash 碰撞,採用了分表儲存,具體可以檢視 FileStore。js 的原始碼來了解更多。
FileStore分表快取策略。png
二、metro 快取到哪裡去了
知道了 metro 的快取機制,那麼這個快取到底儲存在本地系統的什麼位置呢?
檢視 FileStore。js 原始碼發現初始化 FileStore 時會傳入一個 root 引數,這個 root 其實就是快取儲存的路徑。所以我們只要知道 FileStore 在哪裡初始化的,就能知道快取的地址了。
FileStore建構函式。png
建立目錄。png
在 start 的時候我們沒有指定 metro 的配置,所以 metro 的配置都是從 node_modules/metro-config/defaults/index。js 中讀取的預設配置,在這裡可以看到快取的初始化程式碼,如下:
cacheStores: [ new FileStore({ root: path。join(os。tmpdir(), “metro-cache”) })]
快取路徑為 os.tmpdir() 拼接上 "/metro-cache"
那這個 os。tmpdir() 是什麼呢?os 是 node。js 的一個系統庫,tempdir() 獲取的是系統的臨時目錄,其值等於在
Linux
終端下執行如下命令獲取的值:
echo $TMPDIR
最終得出快取地址為:echo $TMPDIR 拼接上 “/metro-cache”,大家可以自行嘗試檢視。
image2021-1-21_16-55-9。png
三、快取導致的問題及解決方案
1、問題
react-native 的快取會導致各種問題,常見的問題為更新了依賴庫,團隊中有的小夥伴能正常執行,有的缺報莫名其妙的錯誤,這是在執行 npm start 時快取帶來的問題,實際上執行 react-native bundle 打包也會有快取問題,所以問題從大類來講有以下兩類:
1. 修改了依賴庫,團隊中有的小夥伴能正常執行,有的則報出莫名其妙的錯誤
2. react-native bundle 打包偶現 找不到 metro-cahce/T/xxxx 檔案錯誤
這兩類問題都是由於 metro 快取導致的。
2、解決方案
既然是快取問題,那麼清除快取就能夠解決問題,有以下幾種方案來清除快取:
重啟電腦
:tempdir 目錄是一個臨時目錄,在重新電腦之後實際上就會被清除,所以 tempdir 目錄下的 metro-cache 目錄也會被清除
手動刪除快取
:終端執行 echo $TMPDIR 獲取 臨時目錄,再拼接上 metro-cache 得到快取目錄,手動刪除 metro-cache 目錄即可
自動刪除快取
:metro打包提供了不少引數,其中就有一個清除快取的引數,只需在執行 start 和 bundle 時帶上 ——reset-cache即可自動刪除快取
react-native start ——reset-cachereact-native bundle ——reset-cache
刪除快取之後再次編譯或者打包時都會變慢,所以一般情況下無需刪除快取。
轉載:
作者:peaktan
連結:https://www。jianshu。com/p/52620bc4b728