Bazel + Angular + SocketIO 原因:Uncaught TypeError: XMLHttpRequest is not a constructor

flo*_*olu 13 socket.io typescript bazel angular

我想将ngx-socket-io添加到我的 Angular 应用程序中。我使用 Bazel 来运行我的 Angular 开发服务器。不幸的是ngx-socket-iots_devserver开箱即用似乎并不适用。我在浏览器控制台中收到此错误:

Uncaught TypeError: XMLHttpRequest is not a constructor
    at ts_scripts.js?v=1587802098203:16776
    at Object.23.../transport (ts_scripts.js?v=1587802098203:16780)
    at o (ts_scripts.js?v=1587802098203:11783)
Run Code Online (Sandbox Code Playgroud)

它似乎是由xmlhttprequest-ssl引起的,它是engine.io-client 的一个依赖项,它是ngx-socket-io. 但是这个问题只发生在ts_devserver 上生产中运行 Angular 应用程序完全正常。

最小复制

你可以自己轻松尝试:https : //github.com/flolu/bazel-socketio-issue

只需运行yarn install然后yarn dev(它会导致浏览器控制台 @ http://localhost:4200 中的错误)。并注意yarn prod@ http://localhost:8080工作正常!

编辑 1

目前,Windows 上似乎还有另一个问题。因此,如果您运行的是 Mac 或 Linux,则只能尝试示例存储库

Seb*_* B. 5

问题来自engine.io-client,由 内部使用socket.io-client

socket.io-client被构建为由触发的 UMD 模块时

     "@npm//socket.io-client:socket.io-client__umd",
Run Code Online (Sandbox Code Playgroud)

BUILD.bazel, 的browser关键engine.io-client/package.json

 "browser": {
   "ws": false,
   "xmlhttprequest-ssl": "./lib/xmlhttprequest.js"
 },
Run Code Online (Sandbox Code Playgroud)

似乎被忽略了。

因此,中的require('xmlhttprequest-ssl')语句node_modules/engine.io-client/lib/transports/*.js保留在 UMD 版本中。因为xmlhttprequest-ssl适用于无头 Node 环境并且在浏览器中不起作用,所以这会导致错误。

我找不到此行为的原因/问题,但我找到了解决方案(不应将其视为解决方法):

engine.io-clientpostinstall脚本重写:

  1. 安装shelljs包:yarn add -D shelljs
  2. 更新postinstallpackage.json到:"postinstall": "node --preserve-symlinks --preserve-symlinks-main ./postinstall-patches.js && ngcc"
  3. 将以下代码放入postinstall-patches.js项目根目录:
     "@npm//socket.io-client:socket.io-client__umd",
Run Code Online (Sandbox Code Playgroud)

(灵感:https : //bazelbuild.github.io/rules_nodejs/#patching-the-npm-packages,链接到示例https://github.com/angular/angular/blob/master/tools/postinstall-patches .js )

  1. yarn install
  2. yarn dev

我将在几分钟内向您的 GitHub 复制提交拉取请求。


可能的替代方案,无法让它们工作:

  • 使用socket.io-client/dist/socket.io.js但带有额外的“UMD 垫片”,因为它似乎是一个“匿名 UMD”模块,或者
  • 一些npm_umd_bundle魔法

有关这两种方式的更多信息,请参阅问题每个新的 npm dep 都需要一种独特的方法如何将其添加到 ts_devserver #1055bazelbuild/rules_nodejs