我的用例如下:
子库的代码
import { NgModule } from '@angular/core';
import {CommonModule} from "@angular/common";
@NgModule({
imports: [CommonModule],
declarations: [
SampleDirective
],
exports: [
SampleDirective
]
})
export class ChildModule { }
子库中指令的代码
import {Directive, PLATFORM_ID, Inject} from '@angular/core';
@Directive({
selector: '.sample'
})
export class SampleDirective {
constructor(@Inject(PLATFORM_ID) private _element: Object) {
}
}
在我安装了子模块的父母中,我正在进行以下简单的单元测试
import {async, ComponentFixture, TestBed} from '@angular/core/testing';
import {Component} from '@angular/core';
import {ChildModule} from "@nz/child-lib";
@Component({
selector: 'nz-host',
template: `
<div class="sample"></div>
`
})
export class TestWrapperComponent{}
describe('injection problem', () => {
let testFixture: ComponentFixture<TestWrapperComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestWrapperComponent],
imports: [ChildModule]
});
}));
beforeEach(async(() => {
testFixture = TestBed.createComponent(TestWrapperComponent);
testFixture.detectChanges();
}));
it('test', () => {
expect(true).toBe(true);
});
});
当我运行测试时,我收到以下错误:
StaticInjectorError [InjectionToken Platform ID]: NullInjectorError:没有InjectionToken平台ID的提供者! 错误:StaticInjectorError [InjectionToken Platform ID]: 在_NullInjector.get(webpack:///node_modules/@angular/core/esm5/core.js:923:0&lt; - spec.bundle.js:3517:19) at resolveToken(webpack:///node_modules/@angular/core/esm5/core.js:1211:0&lt; - spec.bundle.js:3805:24) 在tryResolveToken(webpack:///node_modules/@angular/core/esm5/core.js:1153:0&lt; - spec.bundle.js:3747:16) 在StaticInjector.get(webpack:///node_modules/@angular/core/esm5/core.js:1024:0&lt; - spec.bundle.js:3618:20) at resolveToken(webpack:///node_modules/@angular/core/esm5/core.js:1211:0&lt; - spec.bundle.js:3805:24) 在tryResolveToken(webpack:///node_modules/@angular/core/esm5/core.js:1153:0&lt; - spec.bundle.js:3747:16) 在StaticInjector.get(webpack:///node_modules/@angular/core/esm5/core.js:1024:0&lt; - spec.bundle.js:3618:20) at resolveNgModuleDep(webpack:///node_modules/@angular/core/esm5/core.js:10584:0&lt; - spec.bundle.js:13178:25) 在NgModuleRef_.get(webpack:///node_modules/@angular/core/esm5/core.js:11805:0&lt; - spec.bundle.js:14399:16) at resolveDep(webpack:///node_modules/@angular/core/esm5/core.js:12301:0&lt; - spec.bundle.js:14895:45)
我的 package.json 是:
"dependencies": {
"tslib": "^1.7.1"
},
"peerDependencies": {
"@angular/common": ">= 5.0.0",
"@angular/core": ">= 5.0.0"
},
"devDependencies": {
"@angular/animations": "5.0.0",
"@angular/common": "5.0.0",
"@angular/compiler": "5.0.0",
"@angular/compiler-cli": "5.0.0",
"@angular/core": "5.0.0",
"@angular/platform-browser": "5.0.0",
"@angular/platform-browser-dynamic": "5.0.0",
"@angular/platform-server": "5.0.0",
"@compodoc/compodoc": "1.0.3",
"@nz/child-lib": "^0.0.1",
"@types/jasmine": "2.6.2",
"@types/node": "8.0.47",
"chalk": "2.3.0",
"codelyzer": "4.0.2",
"core-js": "2.5.1",
"istanbul-instrumenter-loader": "3.0.0",
"jasmine-core": "2.8.0",
"karma": "1.7.1",
"karma-chrome-launcher": "2.2.0",
"karma-coverage-istanbul-reporter": "1.3.0",
"karma-jasmine": "1.1.0",
"karma-sourcemap-loader": "0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "2.0.5",
"reflect-metadata": "0.1.10",
"rollup": "0.50.0",
"rollup-plugin-license": "0.5.0",
"rollup-plugin-node-resolve": "3.0.0",
"rollup-plugin-sourcemaps": "0.4.2",
"rxjs": "5.5.2",
"shelljs": "0.7.8",
"source-map-loader": "0.2.3",
"ts-loader": "3.1.1",
"tslint": "5.8.0",
"tslint-angular": "1.0.0",
"typescript": "2.4.2",
"uglify-js": "3.1.6",
"webpack": "3.8.1",
"zone.js": "0.8.18"
}
即使使用以下代码模拟PLATFORM_ID
{provide: PLATFORM_ID, useValue: 'browser'}
错误仍然存在。
包作为符号链接
我有一个新的理论,为什么它发生在我的最后。 我认为,因为我使用 lerna 来管理我的包和包依赖。 由于我通过lerna将子模块添加到主机模块,因此lerna在主机的节点模块中创建子模块的符号链接。 所以我的理论是,当我们使用的库是符号链接时,DI无法识别他需要注入的内容。 试图找出如何使用--preserve-symlinks
运行测试非常感谢
答案 0 :(得分:3)
所以问题确实是符号链接。 在node_modules中使用符号链接或使用lerna(将内部包与symlink链接)等包管理工具时。 比角度不会知道如何正确地注入物品。
我的解决方案是在运行测试之前删除符号链接,用硬拷贝安装包,然后运行测试。
答案 1 :(得分:0)
我在Angular 6多模块项目和Lerna中遇到了相同的问题。
首先,在Angular配置文件(Angular 6中的preserveSymLinks
)中有一个名为true
的选项可以设置为angular.json
。
在那之后,我能够使用symbolik链接而不是Lerna链接将模块链接到我的项目。我不知道为什么,但是我必须在Windows环境中使用mklink命令来完成此操作。