Angular依赖注入异常:OpenAPI生成代码作为外部模块加载失效
Angular 外部API模块引入后出现ASSERTION ERROR问题
我基于OpenAPI YAML,用ng-openapi-gen工具生成了Angular Web服务客户端代码。在同一Angular项目内生成时运行正常,但打包成独立项目上传到NEXUS服务器,再通过package.json引入到前端项目后就失效了。
本地运行正常的代码示例
AppModule代码(app.module.ts)
import { ApiModule } from '../../generated/ts/api.module' @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, ApiModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule {}
AppComponent代码(app.component.ts)
import { ApiService } from '../../generated/ts/services/api.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'], }) export class AppComponent { title = 'demo'; hello: any; constructor(private apiService: ApiService) {} public sayHello() { this.apiService.helloworldGet().subscribe((e: HelloWorld200) => { this.hello = e; }); } }
迁移到外部模块后的修改
仅修改了导入路径,其余代码、YAML配置、加载逻辑完全一致,生成的代码现在位于node_modules目录下:
import { ApiService } from 'api-service-project/generated/ts/services/api.service';
此时浏览器控制台报错:
ERROR Error: ASSERTION ERROR: token must be defined [Expected=> null != undefined <=Actual]
相关配置文件
API服务项目的package.json
{ "name": "api-service-project", "version": "1.1.2", "description": "Demo API", "main": "index.js", "scripts": { "test": "echo \"Tests are not written yet\" && exit 0", "generate:api": "ng-openapi-gen --input ./src/main/resources/api.yaml --output ./generated/ts", "prebuild": "npm run generate:api", "build": "npm pack" }, "files": [ "./generated/ts", "./src/main/resources/api.yaml" ], "dependencies": { "@angular/core": "^15.0.0", "@angular/common": "^15.0.0", "rxjs": "^7.4.0" }, "author": "...", "license": "ISC", "publishConfig": { "registry": "https://nexus..." }, }
前端应用的package.json
{ "name": "frontend-application", "version": "0.0.0", "scripts": { "ng": "ng", "start": "ng serve", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test" }, "private": true, "dependencies": { "@angular/animations": "^15.0.0", "@angular/common": "^15.0.0", "@angular/compiler": "^15.0.0", "@angular/core": "^15.0.0", "@angular/forms": "^15.0.0", "@angular/platform-browser": "^15.0.0", "@angular/platform-browser-dynamic": "^15.0.0", "@angular/router": "^15.0.0", "api-service-project": "^1.1.0", // <------ 引入的API模块 "rxjs": "^7.4.0", "tslib": "^2.3.0", "zone.js": "~0.12.0" }, "devDependencies": { "@angular-devkit/build-angular": "^15.0.4", "@angular/cli": "~15.0.4", "@angular/compiler-cli": "^15.0.0", "@types/jasmine": "~4.3.0", "jasmine-core": "~4.5.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.0.0", "typescript": "~4.8.2" } }
问题排查与解决方案
1. 锁定Angular依赖版本
API服务项目的Angular依赖不要用^15.0.0这种范围版本,直接和前端项目的Angular版本保持完全一致(比如15.0.0),避免版本差异导致注入器冲突。
2. 修正API模块的package.json配置
- 移除无效的
main字段,改为指向生成的ApiModule入口,同时添加types字段指定TypeScript类型入口:"main": "./generated/ts/api.module.js", "types": "./generated/ts/api.module.d.ts" - 在API模块根目录添加
index.ts,统一导出核心模块和服务:
这样前端项目可以直接通过包名导入:export * from './generated/ts/api.module'; export * from './generated/ts/services/api.service';import { ApiModule, ApiService } from 'api-service-project';
3. 配置前端项目的TypeScript编译
在前端项目的tsconfig.json中,确保包含API模块的源码目录:
"include": [ "src/**/*", "node_modules/api-service-project/generated/ts/**/*" ]
4. 正确初始化ApiModule
导入ApiModule时使用forRoot方法配置必要参数(比如API基础路径),确保模块内的提供者正确初始化:
@NgModule({ imports: [ BrowserModule, ApiModule.forRoot({ basePath: 'https://your-api-domain' }) ] }) export class AppModule {}
5. 编译API模块后再发布
不要直接发布TypeScript源码,先在API服务项目中执行Angular编译命令,将生成的代码编译为JavaScript后再打包发布,避免前端项目编译时出现问题。
内容的提问来源于stack exchange,提问作者30thh
相关产品推荐
相关产品推荐

