升级到 Angular 11 后获得 "inject() must be called from an injection context"

Getting "inject() must be called from an injection context" after upgrading to Angular 11

升级到 Angular 11 后,我无法再 ng serve 我的网络应用程序了。

我正在使用 Spring Doc 和最新的 OpenAPI 生成器 gradle-plutin (5.0.0) 生成客户端。

问题似乎与我的(生成的)REST 客户端有关。打开 https://localhost:4200 会将以下内容写入控制台:

main.ts:12 Error: inject() must be called from an injection context
    at injectInjectorOnly (core.js:4901) [angular]
    at Module.ɵɵinject (core.js:4911) [angular]
    at Object.ApiModule_Factory [as factory] (meditation-rest-client.js:2885) [angular]
    at R3Injector.hydrate (core.js:11158) [angular]
    at R3Injector.get (core.js:10979) [angular]
    at :4200/vendor.js:82591:55 [angular]
    at Set.forEach (<anonymous>) [angular]
    at R3Injector._resolveInjectorDefTypes (core.js:11016) [angular]
    at new NgModuleRef (core.js:25046) [angular]
    at NgModuleFactory.create (core.js:25100) [angular]
    at :4200/vendor.js:100468:45 [angular]
    at Object.onInvoke (core.js:28301) [angular]

以下是我的tsconfig.json文件:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

这就是我在 package.json

中定义依赖关系的方式
    "chart.js": "^2.9.4",
    "core-js": "^3.8.2",
    "meditation-rest-client": "./generated/meditation-rest-client",
    "http-server": "^0.12.3",
    "http-status-codes": "^2.1.4",
    "moment": "^2.29.1",

这是上面错误消息中提到的那些生成的行:

// ...

ApiModule.ɵmod = ɵngcc0.ɵɵdefineNgModule({ type: ApiModule });
ApiModule.ɵinj = ɵngcc0.ɵɵdefineInjector({ factory: function ApiModule_Factory(t) { return new (t || ApiModule)(ɵngcc0.ɵɵinject(ApiModule, 12), ɵngcc0.ɵɵinject(ɵngcc1.HttpClient, 8)); }, providers: [], imports: [[]] });
ApiModule.ctorParameters = () => [
    { type: ApiModule, decorators: [{ type: Optional }, { type: SkipSelf }] },
    { type: HttpClient, decorators: [{ type: Optional }] }
];

// ...

这曾经在 Angular 9 中有效,但在 Angular 11 中无效。

知道如何解决这个问题吗?我已经尝试按照建议设置 "preserveSymlinks": true here and here

如果您需要更多信息,请告诉我。

问题可能是由于生成的 npm 包构建到某个输出文件夹 /generated/meditation-rest-client 引起的。 当被前端应用程序引用时,api 包将导入 @angular/core 解析为 /generated/meditation-rest-client/node_modules/@angular/core,不同于项目根目录中的 /node_modules/@angular/core

解决方案是删除 /generated/meditation-rest-client/node_modules 文件夹和父文件夹中的 node_modules 文件夹,<project-root>/node_modules 除外。或者,应将生成的代码 /generated/meditation-rest-client 复制到父文件夹不包含 node_modules 文件夹的某个位置。

https://github.com/OpenAPITools/openapi-generator/issues/8447

如果这是一个多项目设置(又名 monorepo),您必须注意以下事项:

  • 根目录(包含 projects 子目录的文件夹)应该有一个 package.json 和一个 node_modules 目录
  • 只有 library 类型的项目有 package.json 并且它们应该只有对等依赖项。 不要 运行 npm install 这里!这里不能有 node_modules 目录
  • 申请项目根本没有 package.json,因此也没有 node_modules
  • 库不需要列为依赖项。使用 tsconfig.jsoncompilerOptions 中的路径来使用它。

我在 github 发现这个示例骨架项目有助于解决我的注入问题:

https://github.com/PeterKassenaar/ng-monorepo