遵循Angular官方指南时遇TSLint与RouterLinkStubDirective错误
解决RouterLinkStub引发的TSLint和JIT编译问题
我之前在模拟RouterLink写组件测试的时候也踩过一模一样的坑!给你几个实战有效的解决办法:
1. 彻底隔离测试用Stub指令(最推荐)
问题根源在于你可能把RouterLinkStub指令加到了生产环境的NgModule里(比如AppModule或共享模块),或者测试配置没做好,导致TSLint和JIT编译器都认为这个指令需要在正式模块中声明。
正确的做法是:只在测试专用的模块中声明RouterLinkStub,完全不碰生产代码的模块配置。
举个测试文件里的例子:
// your-component.spec.ts import { ComponentFixture, TestBed } from '@angular/core/testing'; import { YourComponent } from './your.component'; import { RouterLinkStub } from './router-link-stub.directive'; describe('YourComponent', () => { let component: YourComponent; let fixture: ComponentFixture<YourComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ YourComponent, RouterLinkStub // 只在测试模块里声明这个Stub指令 ] }).compileComponents(); }); // ... 测试逻辑 });
如果多个测试文件都需要用这个Stub,可以创建一个TestingSharedModule,专门在测试环境导入:
// testing-shared.module.ts import { NgModule } from '@angular/core'; import { RouterLinkStub } from './router-link-stub.directive'; @NgModule({ declarations: [RouterLinkStub], exports: [RouterLinkStub] }) export class TestingSharedModule {}
然后在测试文件里导入这个模块就行:
await TestBed.configureTestingModule({ declarations: [YourComponent], imports: [TestingSharedModule] }).compileComponents();
这样做之后,TSLint就不会再报错,生产环境的JIT编译也不会检测到这个测试用指令。
2. 针对性调整TSLint规则(应急方案)
如果暂时没法隔离测试代码,可以在tslint.json里给测试文件添加规则例外,忽略“指令必须在NgModule中声明”的报错:
{ "rules": { "directive-selector": [ true, "attribute", "app", "camelCase" ], // 给测试文件添加例外 "no-unused-declaration": { "severity": "warning", "exclude": ["src/**/*.spec.ts", "src/**/*-stub.ts"] } } }
不过这个方案只是治标,还是推荐第一种隔离的方式更规范。
3. 排查生产环境的JIT报错
如果应用在JIT模式下报错,大概率是RouterLinkStub被意外打包进了生产代码。你需要检查:
- 主AppModule和所有共享模块,确保没有声明或导入
RouterLinkStub - 检查
angular.json的build配置,确认spec文件和stub文件被排除在生产构建之外:"projects": { "your-app": { "architect": { "build": { "options": { "exclude": ["src/**/*.spec.ts", "src/**/*-stub.ts"] } } } } }
内容的提问来源于stack exchange,提问作者Usman Tahir
相关产品推荐
相关产品推荐

