RN調試


https://facebook.github.io/react-native/docs/debugging.html

熱加載

  RN的目標是極致的開發體驗,修改文件后能在1秒內看到變化,通過以下三個特征來實現:

  1. js的編譯時間短
  2. 本地packager服務器可以把源文件(ES6,JSX,flow等)轉換為通用的js代碼,使用多個核心,轉換中用到的中間代碼保存在內存中,用於下次更快的增量修改
  3. 內置了live reload自動刷新

  有了以上功能,剩余的瓶頸就是刷新后會丟失app當前的狀態,手動還原了當前要調試的狀態需要花費比較多時間。解決這個問題需要在app運行的時候動態注入新的代碼,這樣app的狀態就不會丟失了。

  因為js是有狀態,所以熱加載並不是十分完美。熱加載在大部分時候是管用的,但出現意外后可以使用reload全部刷新,全部刷新總是很管用的。在RN0.22以后,點擊開發者菜單的enable hot reloading啟用熱加載。

熱加載原理

  RN中的熱加載是通過packager實現的,基礎是webpack的hmr。packager通過hmr來檢測文件變化,然后發送HMR update(包含了更新的模塊代碼以及json格式的模塊間的依賴關系)到app里邊的hmr runtime,接着runtime就會把新的代碼替換上去。

  哪一個模塊被修改了,那個模塊就會收到一個hmr update。hmr update必須要被accept,否則會一直沿着依賴鏈往上傳遞。hmr update所經過的模塊,這個模塊的緩存就會被清除。

  熱加載中,accept的刪除是無效的,只能被替換和添加,替換和添加會馬上生效。如C中沒有accept,往C中添加一個accept,則C的代碼會重新執行,剛添加的accept回調函數也會執行。

  哪個模塊把hmr update accept了,這個模塊的代碼會重新執行(如果這個hmr update是從依賴的模塊里傳遞上來的,則這個依賴也會被重新執行,因為這個依賴的緩存被清除過了),最后再調用accept的回調函數。假如A中有accept並且accept了一個hmr update,則A重新執行了。但是如果依賴於A的模塊B早就require了A,則B使用的也還是舊緩存A,在B中需要再次require A才能獲取到讀取最新的A代碼。

  對於react組件的熱加載有些困難。在組件的jsx轉換時,轉換器會為每個組件都創建一個與之對應的代理和一個accept函數(里面的代碼可以強制重新渲染頁面),這些代理管理組件的狀態並且觸發對應組件的生命周期方法。這樣就可以直接替換代碼而且不會丟失狀態了,因為狀態保存在代理中,代理不會發生變化。使用這種轉換需要配置babel-preset-react-native,如果要用在webpack中則使用react-transform

  明白了以上的道理后,下面這個例子也很好理解了:

// configureStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducer from '../reducers';

export default function configureStore(initialState) {
  const store = createStore(
    reducer,
    initialState,
    applyMiddleware(thunk),
  );

  if (module.hot) {
    module.hot.accept(() => {
      const nextRootReducer = require('../reducers/index').default;
      store.replaceReducer(nextRootReducer);
    });
  }

  return store;
};

  當reducers發生變化后,reducers中沒有accept,所以hmr update往上傳遞到了上面這個store中,hmr update在這里被accept了,然后就把最新的reducer替換上去了。

API

  在需要被熱更新的模塊內寫上:

module.hot.accept(() => { console.log('changed'); });

  當模塊代碼被改變時,以上回調函數中的代碼就會被執行。在少數情況下需要手動調用這個API,大部分時候,RN中的熱加載是開箱即用的,而不需要自己寫任何代碼

自動刷新

  啟用開發者菜單中的enable live reload,當源文件發生變化時,packager會通知app重新刷新,會再次讀取js bundle,js bundle會被packager再次打包然后響應回給app。

  當往資源目錄中添加了資源(如圖片)或者修改了native原生代碼,需要重新構建app。

錯誤和警告

  錯誤和警告在開發模式下會顯示到app界面上。

  當app內發生錯誤,或者調用了console.error,則app界面會顯示一個紅色全屏的錯誤信息;當出現警告,或者調用了console.warn,則app底部會出現一個黃色工具欄顯示警告信息。

在chrome中調試js

  點擊開發者菜單,啟用debug js remotely。這會打開一個chrome標簽(http://localhost:8081/debugger-ui)。在這個標簽中打開調試窗口,可以看到app內的console輸出,進入source,對js打斷點,還可以進行js調試

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM