【webpack】记录hmr失效解决方案

前言

最近遇到个问题,由于登陆系统使用单点登陆加应用使用微前端,开发时使用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端口,该文件位置位于_@pmmmwh_react-refresh-webpack-plugin@0.5.1下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);
  • 即可进行热重载。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值