升级到 Angular 11 后获取“必须从注入上下文调用注入()”

Posted

技术标签:

【中文标题】升级到 Angular 11 后获取“必须从注入上下文调用注入()”【英文标题】:Getting "inject() must be called from an injection context" after upgrading to Angular 11 【发布时间】:2021-04-18 22:32:38 【问题描述】:

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

我正在使用 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$1 (core.js:25046) [angular]
    at NgModuleFactory$1.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 下无法使用。

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

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

【问题讨论】:

【参考方案1】:

如果这是一个多项目设置(又名 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

【讨论】:

【参考方案2】:

由于生成的 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_modulesnode_modules 文件夹,&lt;project-root&gt;/node_modules 除外。或者,应将生成的代码 /generated/meditation-rest-client 复制到父文件夹不包含 node_modules 文件夹的某个位置。

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

【讨论】:

以上是关于升级到 Angular 11 后获取“必须从注入上下文调用注入()”的主要内容,如果未能解决你的问题,请参考以下文章

将 Angular 应用程序从 6 升级到 10 更新后会产生很多错误

升级后或新项目无法构建 Angular 12 和 Webpack 5

从 Angular 11 升级到 12 会导致对等依赖冲突

将 Angular 11 应用程序升级到 Angular 12 时面临的问题

编译 Angular 11(从 Angular 9 升级)应用程序时出错

升级到 9.0 和 angular 7 后修复 angular-redux/store