前言
最近遇到个问题,由于登陆系统使用单点登陆加应用使用微前端,开发时使用xswitch插件进行拦截代理,然后导致每次修改完代码需要手动刷新浏览器更新。特此寻找了解决方法。后发现每次都会刷新浏览器而不是热重载,经过探索后成功不刷新浏览器热重载。
解决方法
1、首先需要保证ws服务正常。由于未使用localhost域名导致会尝试建立访问域名的ws服务。
- 找到node_modules下_react-dev-utils这个包
- 其中有个文件叫webpackHotDevClient.js文件,第58行修改协议host和端口:
process.env.WDS_SOCKET_HOST = '127.0.0.1';
// Connect to WebpackDevServer via a socket.
var connection = new WebSocket(
url.format({
protocol: 'ws',
hostname: process.env.WDS_SOCKET_HOST || window.location.hostname,
port: 改成自己启动的端口,
// Hardcoded in WebpackDevServer
pathname: process.env.WDS_SOCKET_PATH || '/sockjs-node',
slashes: true,
})
);
- 找到node_modules下的_webpack-dev-server 版本3.11.2,其中client下utils下的createSocketUrl.js文件里第77行修改配置:
return url.format({
protocol: 'http',
auth: auth,
hostname: '127.0.0.1',
port: sockPort,
// If sockPath is provided it'll be passed in via the resourceQuery as a
// query param so it has to be parsed out of the querystring in order for the
// client to open the socket to the correct location.
pathname: sockPath
});
- 此时ws可以连接,启动后会发现ws成功连接,但是每次修改代码后,会进行刷新浏览器。
- 经断点研究后发现,修改代码后,会查找该代码块,但是该代码块不支持热更新,貌似是module.hot._main_是true就直接throw出unaccept,导致刷浏览器。
- 正常来说react-dev-utils已处理了module.hot等逻辑,不需要侵入性再写逻辑,可能是由于这个模块工作不正常。但研究半天未发现有啥问题。于是使用新开服务的方式去解决这个问题。
- 增加额外代码有2个库可以用,一个是react-refresh,一个是react-hot-loader。首先尝试使用react-refresh,因为dan说react-refresh后续会替代react-hot-loader,并且react-hot-loader不进行维护的原因就是因为出现了react-refresh。
- 使用react-refresh时发现ws连接也没连上,同样硬编码进去修改host端口,该文件位置位于_@[email protected]下sockets/utils/getSocketUrlParts.js 109行。后续连接后发现仍然无法进行热更新,也没有报错,于是换成使用react-hot-loader。
- 经配置后发现react-hot-loader可以进行热更新且不刷新浏览器。
- 需要先给dev-server开启hot:
"devServer": {
"historyApiFallback": true,
"hot": true
},
- 增加入口与babel-plugin:
config
.toConfig()
.entry.app.unshift(require.resolve('react-hot-loader/patch'));
config.toConfig().module.rules.forEach((v, i) => {
if ((v.test + '').includes('jsx')) {
v.use.forEach((k) => {
if (k.loader.includes('babel-loader')) {
k.options.plugins.push(require.resolve('react-hot-loader/babel'));
}
});
}
});
- 根组件中套入hot:
import {
hot } from 'react-hot-loader/root';
class Appx extends React.PureComponent {
...
render() {
return (
<Provider store={
store}>
...
</Provider>
);
}
}
const App = hot(Appx);
- 即可进行热重载。