升级到 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.json
的 compilerOptions
中的路径来使用它。
我在 github 发现这个示例骨架项目有助于解决我的注入问题:
升级到 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.json
的compilerOptions
中的路径来使用它。
我在 github 发现这个示例骨架项目有助于解决我的注入问题: