Closed rookit-ljt closed 1 week ago
类组件不支持热更,换函数组件吧。
// crates/mako/src/visitors/react.rs
fn react_refresh_module_prefix(context: &std::sync::Arc<Context>) -> Box<dyn VisitMut> {
let mut code = r#"
import * as RefreshRuntime from 'react-refresh';
var prevRefreshReg;
var prevRefreshSig;
prevRefreshReg = self.$RefreshReg$;
prevRefreshSig = self.$RefreshSig$;
self.$RefreshReg$ = (type, id) => {
RefreshRuntime.register(type, module.id + id);
};
self.$RefreshSig$ = () => " %exports%";
"#
.to_string();
// check react hmr ability if react was externalized in development mode
if context.config.mode == Mode::Development
&& context
.config
.externals
.keys()
.any(|x| x == "react" || x == "react-dom")
{
code = format!(
r#"
if (!(typeof window !== 'undefined' ? window : globalThis).__REACT_DEVTOOLS_GLOBAL_HOOK__) {{
console.warn('HMR is not available for React currently! Because React was externalized, please install the React Developer Tools extension to enable React Refresh feature. https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react');
}}
{}
"#,
code
);
}
Box::new(PrefixCode {
context: context.clone(),
code,
})
}
fn react_refresh_module_postfix(context: &Arc<Context>) -> Box<dyn VisitMut> {
Box::new(PostfixCode {
context: context.clone(),
// why add `if (prevRefreshReg)` guard?
// ref: https://github.com/umijs/mako/issues/971
code: r#"
if (prevRefreshReg) self.$RefreshReg$ = prevRefreshReg;
if (prevRefreshSig) self.$RefreshSig$ = prevRefreshSig;
function $RefreshIsReactComponentLike$(moduleExports) {
if (RefreshRuntime.isLikelyComponentType(moduleExports)) {
RefreshRuntime.register(moduleExports, module.id + ' %exports%');
return true;
}
if (RefreshRuntime.isLikelyComponentType(moduleExports.default)) {
RefreshRuntime.register(moduleExports.default, module.id + ' %exports%');
return true;
}
for (var key in moduleExports) {
try{
if (RefreshRuntime.isLikelyComponentType(moduleExports[key])) {
RefreshRuntime.register(moduleExports[key], module.id + ' %exports%');
return true;
}
}catch(e){
// in case the moduleExports[key] is not accessible due depedence loop
}
}
return false;
}
if ($RefreshIsReactComponentLike$(module.exports)) {
module.meta.hot.accept();
RefreshRuntime.performReactRefresh();
}
"#
.to_string(),
})
}
https://github.com/vitejs/vite-plugin-react/blob/1609186b9f379d4c1cf75c60e878d8b4f7675ab3/packages/plugin-react/src/refreshUtils.js#L14-L26
参考 vite-plugin-react
重写了 hmr 部分的逻辑,实际上可以支持 class Component
的热重载,但是不知道是否有其他问题。
What is actually happening? 1 .在函数组件中修改代码后,热更新正常更新视图。 2 .在类组件中修改代码后,热更新无法更新页面视图,要手动刷新页面才能显示修改后的视图。
system:macos 15.0 chrome:127.0.6533.99 umi:3.5.42 umi-plugin-mako: 0.0.4
mako react demo 最小复现
What is expected? 希望类组件中修改代码也能正常更新页面视图