React Native 編譯打包的快取問題

一、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 的原始碼來了解更多。

React Native 編譯打包的快取問題

FileStore分表快取策略。png

二、metro 快取到哪裡去了

知道了 metro 的快取機制,那麼這個快取到底儲存在本地系統的什麼位置呢?

檢視 FileStore。js 原始碼發現初始化 FileStore 時會傳入一個 root 引數,這個 root 其實就是快取儲存的路徑。所以我們只要知道 FileStore 在哪裡初始化的,就能知道快取的地址了。

React Native 編譯打包的快取問題

FileStore建構函式。png

React Native 編譯打包的快取問題

建立目錄。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”,大家可以自行嘗試檢視。

React Native 編譯打包的快取問題

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