React Native调试源码分析——HMR

本文深入探讨了React Native的热模块替换(HMR)机制,包括HMR的通讯方式、HMRClient的工作原理,以及从HMRServer到HMRClient的整个流程,揭示了在代码修改后如何实现即时更新且不丢失应用状态。
摘要由CSDN通过智能技术生成

1、前言

   上次的远程加载简单描述了app reload(开发时运行也是一个逻辑)和MetroServer交互的流程,现在开始讲讲HMR,对应到RN调试界面中的Enable HotLoading,HMR全名为Hot Module Replacement。它能让你在修改代码后马上在app上展现结果而且不会丢失状态。

2、HMR通讯方式

  先看其创建的位置,也是在runServer中

//metro/src/index.js.flow

exports.runServer = async (
......
) => {
....
  const {
    attachHmrServer,
    middleware,
    metroServer,
    end,
  } = await exports.createConnectMiddleware(config);
  serverApp.use(middleware);
....

  let httpServer;
.....
    httpServer = http.createServer(serverApp);
....

  if (hmrEnabled) {
    attachHmrServer(httpServer);
  }

来看看attachHmrServer函数:

index.js.flow

attachHmrServer(httpServer: HttpServer | HttpsServer) {
      attachWebsocketServer({
        httpServer,
        path: '/hot',
        websocketServer: new MetroHmrServer(
          metroServer.getBundler(),
          metroServer.getCreateModuleId(),
          config,
        ),
      });
    }

这里没有逻辑,放出attachWebsocketServer代码:
module.exports = function attachWebsocketServer<TClient: Object>({
  httpServer,
  websocketServer,
  path,
}: HMROptions<TClient>) {
  const WebSocketServer = require('ws').Server;
  const wss = new WebSocketServer({
    server: httpServer,
    path,
  });

  wss.on('connection', async ws => {
    let connected = true;
    const url = ws.upgradeReq.url;

    const sendFn = (...args) => {
      if (connected) {
        ws.send(...args);
      }
    };

    const client = await websocketServer.onClientConnect(url, sendFn);
...
    ws.on('error', e => {
      websocketServer.onClientError && websocketServer.onClientError(client, e);
    });
    ws.on('close', () => {
      websocketServer.onClientDisconnect &&
        websocketServer.onClientDisconnect(client);
      connected = false;
    });
    ws.on('message', message => {
      websocketServer.onClientMessage &&
        websocketServer.onClientMessage(client, message);
    });
  });
};

attachWebsocketServer里面主要是创建WebSocketServer并监听连接,将逻辑全交给MetroHmrServer处理,不得不说这代码把连接和逻辑处理分得很清楚

在来看MetroHmrServer:

//HmrServer.js.flow
 
 async onClientConnect(
    clientUrl: string,
    sendFn: (data: string) => void,
  ): Promise<?Client> {
    const urlObj = nullthrows(url.parse(clientUrl, true));
    const query = nullthrows(urlObj.query);

    let revPromise;
    if (query.bundleEntry != null) {
      urlObj.pathname = query.bundleEntry.replace(/\.js$/, '.bundle');
      delete query.bundleEntry;

      const {options} = parseOptionsFromUrl(
        url.format(urlObj),
        new Set(this._config.resolver.platforms),
      );

      const {entryFile, trans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值