【问题标题】:Howto re-route webpack hot reload client?如何重新路由 webpack 热重载客户端?
【发布时间】:2020-01-27 17:32:10
【问题描述】:

我有一个使用 create-react-app 和 typescript 创建的应用程序。这个应用程序是一个 oauth2 客户端,它需要一个带有 https 的有效 redirect_uri。它还使用 websockets。我可以设置一个接受 https 和 wss 连接的 nginx 服务器,并将它们转发到我的开发机器。

它应该是这样工作的:

web浏览器--> https和wss请求--> nginx--> ssh隧道(remoteforward)--> 开发机--> 本地webpack和本地应用服务器

Nginx 将所有 https 请求映射到 localhost:3000,并将所有 wss 请求(/api 下的任何内容)映射到 localhost:9091。这些通过 ssh 隧道转发到本地开发机器。本地开发机器在 3000 端口上运行 webpack,在 9091 端口上运行 appserver。

这允许我开发一个有效的基于 Web 的 oauth2 客户端,具有有效的 https 证书和 redirect_uri 值。这个设置工作了很长时间。今天我更新了所有的包(包括 node js、create-react app 和 webpack),它停止工作了。这是跟踪日志:

SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
./node_modules/react-dev-utils/webpackHotDevClient.js
node_modules/react-dev-utils/webpackHotDevClient.js:60
__webpack_require__
/home/my_user/projects/my_project/frontend/webpack/bootstrap:785

当然,问题在于 webpack 使用 websockets 进行热重载通知,并且默认代码假定 webpack 服务器在 ws://localost 可用。实际上,该页面是使用 https 加载的。因此,热重载代码尝试从使用 https 加载的页面创建到 ws://localhost 的不安全 websocket。

由于 oauth2 客户端必须使用 https,显而易见的解决方案是完全关闭热重载。但这会减缓发展。为了有效地工作,我需要热重载。这只有在我也可以将热重载客户端的 websocket 从 nginx 转发到我的本地 webpack 服务器时才有效。换句话说:让它通过 wss:// 而不是 ws:// 工作。

但是,我不知道该怎么做。甚至可以重新路由热重载客户端吗?有选择吗?我可以看到可以关闭热重载。但我看不到任何方法可以重新路由 websocket 的 URL。

更新 - 这不再需要,已在 v3.3.1 https://github.com/facebook/create-react-app/pull/8079 中解决。但仍有一些软件包依赖于旧版本。在这些情况下,可以使用下面提供的解决方案。

【问题讨论】:

    标签: node.js webpack websocket create-react-app


    【解决方案1】:

    由于 create-react-app 3.4.0 在您发布后仅几周发布,您现在可以精确这些环境变量:

    • WDS_SOCKET_HOST
    • WDS_SOCKET_PORT
    • WDS_SOCKET_PATH

    查看此提交以获取更多详细信息:create-react-app#822422c

    【讨论】:

    • 这是目前为止最好的答案,刚刚将WDS_SOCKET_PATH=/my-path/sockjs-node 添加到 .env.development 中就可以了!
    【解决方案2】:

    我找到了解决办法。这确实是一个 hack,但它可以用于测试 oauth2 客户端与 https、您自己的 websockets 和 webpack 开发服务器自己的 socks-node websocket同时。

    1. 安装所有必需的软件包
    2. 编辑你的 node_modules/react-dev-utils/webpackHotDevClient.js 文件

    替换这个:

    // Connect to WebpackDevServer via a socket.
    var connection = new WebSocket(
      url.format({
        protocol: 'ws',
        hostname: window.location.hostname,
        port: window.location.port,
        // Hardcoded in WebpackDevServer
        pathname: '/sockjs-node',
      })
    );
    

    有了这个:

    // Connect to WebpackDevServer via a socket.
    var connection = new WebSocket(
      url.format({
        protocol: 'wss',
        hostname: window.location.hostname,
        port: window.location.port,
        // Hardcoded in WebpackDevServer
        pathname: '/sockjs-node',
      })
    );
    

    这将强制 nodejs-socket 使用 wss 而不是 ws。如果 nodejs-socket 也通过你的 web 服务器隧道连接到你的本地 webpack 开发服务器,那么它就可以工作了!

    如果这段代码可以根据 window.location 的协议使用 ws / wss 那就太好了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2019-04-04
      • 2017-01-05
      • 2017-07-07
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      相关资源
      最近更新 更多