【问题标题】:Does react native fast refresh support module.hot.dispose data argument?是否反应原生快速刷新支持 module.hot.dispose 数据参数?
【发布时间】:2021-06-06 06:20:31
【问题描述】:

我正在开发 react-native 故事书项目,我正在尝试重用一些用于将文件(故事)加载到应用程序中的代码。在应用程序的网络版本中,此代码用于跟踪以前的故事文件列表(previousexports),以便在重新加载时不会重复故事。

if (m && m.hot && m.hot.dispose) {
  ({ previousExports = new Map() } = m.hot.data || {});
  m.hot.dispose((data) => {
    loaded = false;
    // eslint-disable-next-line no-param-reassign
    data.previousExports = previousExports;
  });
  m.hot.accept();
}

此代码的链接:https://github.com/storybookjs/storybook/blob/f2cc478dcf1e249c29a1014f7d53d71931f824f8/lib/core-client/src/preview/loadCsf.ts#L237

但是,当我在 react native 上运行此代码时,数据字段未定义。在热模块重载的 webpack 实现中,dispose 函数有这个签名。

__WebpackModuleApi.Hot.dispose(callback: (data: any) => void): void

有这个描述

添加一次性处理程序,当当前模块执行时 代码被替换。在这里,您应该销毁/删除任何持久性 您已声明/创建的资源。如果你想将状态转移到 新模块,将其添加到数据对象。数据将在 module.hot.data 在新模块上。

我正在努力寻找用于热模块更换的反应原生 api。据我所知,快速刷新实现仍然使用类似的 api,并且这些 m.hot 调用是在快速刷新调用时触发的。

react native 是否不支持此数据参数,我在哪里可以找到有关 react-native/metro 的 module.hot api 的信息?

到目前为止,我发现以下内容:

https://github.com/facebook/react/issues/16604#issuecomment-528663101

https://reactnative.dev/blog/2019/09/18/version-0.61#fast-refresh

https://reactnative.dev/blog/2016/03/24/introducing-hot-reloading

有值得注意的信息

快速刷新依赖于多个部分协同工作:

  • 模块系统中的“热模块更换”机制。
    • 这通常也由捆绑程序提供。
    • 例如在 webpack 中,module.hot API 可让您执行此操作。

React Native 中的 HMR 通过引入热对象扩展了模块系统。这个 API 基于 Webpack 的 API。 hot 对象公开了一个名为 accept 的函数,它允许您定义一个回调,该回调将在模块需要热交换时执行。

【问题讨论】:

    标签: javascript react-native storybook


    【解决方案1】:

    自从在这里提出这个问题后,我与一位同事进行了讨论,这让我相信数据参数不受支持。

    同时查看 Metro 代码(react Native 的 Metro 捆绑器)似乎也证实了这一点。

    如果您查看 Metro 存储库中的 require polyfill,您可以看到以下类型定义。

    type HotModuleReloadingCallback = () => void;
    type HotModuleReloadingData = {|
      _acceptCallback: ?HotModuleReloadingCallback,
      _disposeCallback: ?HotModuleReloadingCallback,
      _didAccept: boolean,
      accept: (callback?: HotModuleReloadingCallback) => void,
      dispose: (callback?: HotModuleReloadingCallback) => void,
    |};
    

    如您所见,dispose 函数共享相同的回调签名()=>void

    你可以找到上面代码的源代码here

    我最终选择了一个不同的解决方案,将导出存储在一个全局变量中。这并不理想,但它正在工作。那个全局变量看起来有点像global.previousExports = new Map<any, string>();,我扩展了节点全局类型以避免类型错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-26
      • 2020-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多