[karma-server]: TypeError: Cannot read property 'range' of undefined - Angular Unit Testing in CI environment

[karma-server]: TypeError: Cannot read property 'range' of undefined - Angular Unit Testing in CI environment

我们的 CI/CD 管道停止处理“ng 测试”作业并失败并显示以下错误消息:

[karma-server]: TypeError: Cannot read property 'range' of undefined
    at handleRangeHeaders (/builds/......../node_modules/webpack-dev-middleware/lib/util.js:131:21)
    at processRequest (/builds/......../node_modules/webpack-dev-middleware/lib/middleware.js:98:19)
    at ready (/builds/......./node_modules/webpack-dev-middleware/lib/util.js:53:12)
    at handleRequest (/builds/........../node_modules/webpack-dev-middleware/lib/util.js:182:5)
    at /builds/............/node_modules/webpack-dev-middleware/lib/middleware.js:64:7
    at new Promise (<anonymous>)
    at middleware (/builds/........../node_modules/webpack-dev-middleware/lib/middleware.js:63:12)

添加句点以分出一些特定的回购名称

我们以前从未遇到过此错误,并且以前工作正常。同样奇怪的是,当我在本地 运行 它时它工作得很好。但是当 GitLab 运行 人员执行它时,它失败了。任何帮助,将不胜感激。谢谢!

能够弄清楚。我们在 .gitlab-ci.yml 文件中使用了 node:latest ,无论什么被拉下都会导致问题。 (它看起来是版本 15)。因此,我们将其设置为 node:14.

,而不是 node:latest

这确实是节点 v15 上的业力问题。看起来(目前)它不会被修复,所以降级到 v14 是解决方案:https://github.com/karma-runner/karma/issues/3571

如果您不想更改全局 node 版本,可以安装本地版本 运行 代替。这样一来,无论您 运行 正在使用什么系统,您都可以完全控制自己 运行 正在做什么。

yarn add node@^14.15.0 --dev
// package.json
{
  "scripts": {
    "test": "node_modules/node/bin/node node_modules/.bin/ng test"
  }
}

希望对您有所帮助!

如果您使用 node:latest 和 node:14,就会出现此问题,这是因为 v14.15.2 会出现此问题。如上述答案所述,您应该使用 node:14.15.1,问题就会消失。

TL;DR

  • 在 html 中使用以 assets/... 开头的相对路径。在基于组件的 CSS 中使用向上一级的相对路径:../assets/...
  • 从不,我的意思是从不使用像 /assets 这样以斜杠开头的资产路径,这会在 某些 情况下破坏您的代码
  • 请按照下面的建议进行配置 karma.conf.js 因为 karma 不提供资产并且当前 karma 5.1.1 与 webpack 4.44.2 或其某些插件因上述 OP 错误而崩溃

Post 尸检 (3)

我现在删除了我的第一个 post 死因两次,因为它坏了并引导我到 post 死因 (3) :D

有两点很重要:您需要按照 SO thread.

中的说明调整 karma.conf.js

添加

    proxies: {
      '/assets/': '/base/src/assets/'
      '/Every-single-image-from-css.png': '/base/src/assets/what-ever-the-path-is/Every-single-image-from-css.png'
    },
    files: [
      { pattern: './src/assets/**', watched: false, included: false, nocache: false, served: true }
    ],

config.set({ 部分,是的,即使找不到 base,也要保留 /base/src/assets。 第二部分是您 需要 当前使事情与相对路径一起工作的文件模式。第三部分实际上是 proxies 数组中的第二个条目:分别列出从 css 访问的每个资源:/

重要

ng 预处理路径 somehow strange,上面的代码将导致从 CSS 引用的资产将 重复 并位于root once ng build 完成。非常难看,但我不知道解决此问题的方法,除非仅使用来自 html 的图像,这些图像会得到正确处理。 我注意到 ng serve 扁平化了所有网址。所以即使 css 文件看起来像这样

.my-img{
  background: url('../assets/deeply/nested/logo.png');
}

将作为 /logo.png 来自内置网络服务器。我在查看 ng serve 制作的网站并检查网络调用时检查了这一点。

无论这种行为是什么,ng test 都会因此而死,除非您在代理部分指定 每个单独的 图像。 使用第一个代理条目,例如/assets/ 很有趣,但仅当您使用资产的绝对路径时才有效,当您从 html 中引用图像时,您不应该使用但也被使用,所以 keep它!

由于 ng 编译使 url 扁平化,此代理不适用于 css 引用,因为即使在 ng test 中,来自 css 的图像也会从 root 请求为 /logo.png(剥夺了他们的道路)。不幸的是 proxies 不支持通配符,否则可以将 /*.png 之类的东西写入某些东西。但目前单独列出所有条目似乎是解决方案。

为什么在资产中使用绝对路径是一个愚蠢的想法

我的第一个结果实际上是推荐使用像这样的路径 /assets/foo.png。这样做,只需要提到的 proxies 条目(但它必须看起来有点不同)。 现在我觉得我还好,因为 ng serve 有效,ng test 有效,甚至 ng build 有效。

但是当我想将我的 angular 应用程序部署到一个子目录中时,事情就变糟了。如果你这样做,我找不到任何方法,插手 ng build --base-href '..' 并将一些 --deploy-url 混入其中以使其正常工作。

当您使用资产的绝对路径时,永远不要期望在子目录中工作。

因此,在某些情况下,您可能会幸运地使用我的“错误”方法,但我没有骗您,按照我在上面重复的 @programmerinprogress 的出色建议,您很可能会节省一些时间。

我的项目迁移到 ESLint 后遇到了类似的问题。

我去掉了 tsconfig.app.jsontsconfig.spec.json

两个 Node.JS 版本都没有解决问题,但不知何故我发现了这个 post https://ievgen.de/2020/11/17/angular-tests-fail-docker/ 这基本上是说将以下行添加到你的 karma.conf.js:

proxies: {
  '/assets/': '/base/src/assets/'
},

这解决了我的问题:-)