@taro-hmr-compile/react-refresh
v0.0.3
Published
React Refresh integration for taro-hmr-compile
Readme
@taro-hmr-compile/react-refresh
为 Taro React + Webpack 5 微信小程序提供 React Refresh 编译转换、组件注册和刷新边界处理。在满足刷新条件时,更新组件并保留其状态。
✨ 功能特性
- 自动添加
react-refresh/babel与模块运行时转换。 - 将组件注册和 Hook 签名函数接入 Webpack 模块执行过程。
- 识别组件导出构成的刷新边界,通过
module.hot接受更新。 - 比较边界签名,边界失效时向上触发 HMR 失效处理。
- 合并短时间内的刷新请求,调用
performReactRefresh()。
📦 安装
通常使用 @taro-hmr-compile/preset 即可。手动组合时安装:
pnpm add -D @taro-hmr-compile/react-refresh @taro-hmr-compile/plugin-webpack⚙️ 配置
在现有 Taro 配置中合并:
import { defineConfig } from '@tarojs/cli'
export default defineConfig<'webpack5'>({
framework: 'react',
mini: {
debugReact: true,
},
compiler: {
type: 'webpack5',
prebundle: { enable: false },
},
plugins: [
'@taro-hmr-compile/react-refresh/compiler',
['@taro-hmr-compile/plugin-webpack', { debug: true }],
],
})需要开启 mini.debugReact: true,让小程序使用 React 开发版本。编译插件不接收自定义配置项,仅在 --watch 模式下注入转换,无需手动修改 Babel 配置。
在 project.config.json 中开启 setting.compileHotReLoad: true,并设置 setting.urlCheck: false 以允许配套插件的本地编译请求,然后启动:
pnpm exec taro build --type weapp --watch本包负责 React 刷新集成,完整的页面按需编译与补丁输出由 plugin-webpack 提供。使用 preset 时无需重复注册。
📋 入口说明
| 入口 | 用途 |
| --- | --- |
| @taro-hmr-compile/react-refresh/compiler | Taro 编译插件,注册到 plugins |
| @taro-hmr-compile/react-refresh | 刷新边界与模块运行时函数,由编译转换自动引入 |
业务组件无需手动调用运行时。主要运行时导出如下,供自定义集成参考:
| 导出 | 作用 |
| --- | --- |
| executeRuntime(moduleExports, moduleId, webpackHot) | 注册组件导出并连接模块的 HMR 生命周期 |
| isReactRefreshBoundary(moduleExports) | 判断导出是否构成组件刷新边界 |
| registerExportsForReactRefresh(moduleExports, moduleId) | 将组件导出注册到 React Refresh |
| getReactRefreshBoundarySignature(moduleExports) | 获取刷新边界签名 |
| shouldInvalidateReactRefreshBoundary(prevSignature, nextSignature) | 比较签名,判断边界是否失效 |
| getWebpackHotData(moduleExports) | 生成热更新期间保存的边界信息 |
| createDebounceUpdate() | 创建合并刷新请求的函数,延迟为 30ms |
📝 刷新边界与状态保留
默认导出组件,或仅导出组件的模块,更容易形成独立刷新边界。例如:
import { useState } from 'react'
import { View } from '@tarojs/components'
export default function Counter() {
const [count, setCount] = useState(0)
return <View onClick={() => setCount(value => value + 1)}>计数:{count}</View>
}修改这类组件的展示内容时,在边界和 Hook 签名兼容的情况下可保留状态。混合导出非组件值、改变 Hook 顺序或组件类型,可能使边界失效或触发重新挂载。可以将非组件工具函数、常量放到独立模块,减少对刷新边界的影响。
⚠️ 注意事项
- 当前为 Alpha 版本;仓库示例使用 Taro 4.2.1、React 18、Webpack 5,其他组合需自行验证。
- 编译集成依赖 Taro Webpack 链中的
script规则和babelLoader;自定义替换这些规则时需检查兼容性。 - 模块运行时代码只向
sourceRoot内的文件注入;React Refresh 转换由编译插件统一添加。 - 类组件及不兼容的组件修改不能保证状态保留。
- 修改 Babel 或构建配置后应重启 watch 进程。
完整接入与故障排查见根 README。
📄 许可证
MIT
