fix(core): only warn and auto declare undeclared `entryComponents`.
This is needed to support existing applications. After final these warnings will become errors. Closes #10316
This commit is contained in:
parent
69e72c0786
commit
e44e8668ea
|
@ -351,17 +351,23 @@ export class CompileMetadataResolver {
|
|||
}
|
||||
});
|
||||
moduleMeta.declaredDirectives.forEach((dirMeta) => {
|
||||
dirMeta.entryComponents.forEach((entryComponent) => {
|
||||
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponent.runtime)) {
|
||||
throw new BaseException(
|
||||
`Component ${stringify(dirMeta.type.runtime)} in NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponent.runtime)} via "entryComponents" but it was neither declared nor imported into the module!`);
|
||||
dirMeta.entryComponents.forEach((entryComponentType) => {
|
||||
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponentType.runtime)) {
|
||||
this._addDirectiveToModule(
|
||||
this.getDirectiveMetadata(entryComponentType.runtime), moduleMeta.type.runtime,
|
||||
moduleMeta.transitiveModule, moduleMeta.declaredDirectives);
|
||||
this._console.warn(
|
||||
`Component ${stringify(dirMeta.type.runtime)} in NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported into the module! This warning will become an error after final.`);
|
||||
}
|
||||
});
|
||||
});
|
||||
moduleMeta.entryComponents.forEach((entryComponentType) => {
|
||||
if (!moduleMeta.transitiveModule.directivesSet.has(entryComponentType.runtime)) {
|
||||
throw new BaseException(
|
||||
`NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported!`);
|
||||
this._addDirectiveToModule(
|
||||
this.getDirectiveMetadata(entryComponentType.runtime), moduleMeta.type.runtime,
|
||||
moduleMeta.transitiveModule, moduleMeta.declaredDirectives);
|
||||
this._console.warn(
|
||||
`NgModule ${stringify(moduleMeta.type.runtime)} uses ${stringify(entryComponentType.runtime)} via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,20 +7,33 @@
|
|||
*/
|
||||
|
||||
import {AsyncTestCompleter, beforeEach, ddescribe, xdescribe, describe, expect, iit, inject, beforeEachProviders, it, xit,} from '@angular/core/testing/testing_internal';
|
||||
import {TestComponentBuilder, configureModule} from '@angular/core/testing';
|
||||
import {TestComponentBuilder, configureModule, configureCompiler} from '@angular/core/testing';
|
||||
import {Component, ComponentFactoryResolver, NoComponentFactoryError, forwardRef, ANALYZE_FOR_ENTRY_COMPONENTS, ViewMetadata} from '@angular/core';
|
||||
import {stringify} from '../../src/facade/lang';
|
||||
import {Console} from '../../src/console';
|
||||
|
||||
export function main() {
|
||||
describe('jit', () => { declareTests({useJit: true}); });
|
||||
describe('no jit', () => { declareTests({useJit: false}); });
|
||||
}
|
||||
|
||||
class DummyConsole implements Console {
|
||||
public warnings: string[] = [];
|
||||
|
||||
log(message: string) {}
|
||||
warn(message: string) { this.warnings.push(message); }
|
||||
}
|
||||
|
||||
function declareTests({useJit}: {useJit: boolean}) {
|
||||
describe('@Component.entryComponents', function() {
|
||||
beforeEach(() => { configureModule({declarations: [MainComp, ChildComp, NestedChildComp]}); });
|
||||
var console: DummyConsole;
|
||||
beforeEach(() => {
|
||||
console = new DummyConsole();
|
||||
configureCompiler({useJit: useJit, providers: [{provide: Console, useValue: console}]});
|
||||
configureModule({declarations: [MainComp, ChildComp, NestedChildComp]});
|
||||
});
|
||||
|
||||
it('should error if the component was not declared nor imported by the module',
|
||||
it('should warn and auto declare if the component was not declared nor imported by the module',
|
||||
inject([TestComponentBuilder], (tcb: TestComponentBuilder) => {
|
||||
|
||||
@Component({selector: 'child', template: ''})
|
||||
|
@ -31,9 +44,14 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||
class SomeComp {
|
||||
}
|
||||
|
||||
expect(() => tcb.createSync(SomeComp))
|
||||
.toThrowError(
|
||||
`Component ${stringify(SomeComp)} in NgModule DynamicTestModule uses ${stringify(ChildComp)} via "entryComponents" but it was neither declared nor imported into the module!`);
|
||||
const compFixture = tcb.createSync(SomeComp);
|
||||
const cf = compFixture.componentRef.injector.get(ComponentFactoryResolver)
|
||||
.resolveComponentFactory(ChildComp);
|
||||
expect(cf.componentType).toBe(ChildComp);
|
||||
|
||||
expect(console.warnings).toEqual([
|
||||
`Component ${stringify(SomeComp)} in NgModule DynamicTestModule uses ${stringify(ChildComp)} via "entryComponents" but it was neither declared nor imported into the module! This warning will become an error after final.`
|
||||
]);
|
||||
}));
|
||||
|
||||
|
||||
|
|
|
@ -164,16 +164,6 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||
`Can't export pipe ${stringify(SomePipe)} from ${stringify(SomeModule)} as it was neither declared nor imported!`);
|
||||
});
|
||||
|
||||
it('should error when using an entryComponent that was neither declared nor imported', () => {
|
||||
@NgModule({entryComponents: [SomeComp]})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
expect(() => createModule(SomeModule))
|
||||
.toThrowError(
|
||||
`NgModule ${stringify(SomeModule)} uses ${stringify(SomeComp)} via "entryComponents" but it was neither declared nor imported!`);
|
||||
});
|
||||
|
||||
it('should error if a directive is declared in more than 1 module', () => {
|
||||
@NgModule({declarations: [SomeDirective]})
|
||||
class Module1 {
|
||||
|
@ -281,6 +271,21 @@ function declareTests({useJit}: {useJit: boolean}) {
|
|||
.toBe(SomeComp);
|
||||
});
|
||||
|
||||
it('should warn and auto declare when using an entryComponent that was neither declared nor imported',
|
||||
() => {
|
||||
@NgModule({entryComponents: [SomeComp]})
|
||||
class SomeModule {
|
||||
}
|
||||
|
||||
const ngModule = createModule(SomeModule);
|
||||
expect(ngModule.componentFactoryResolver.resolveComponentFactory(SomeComp).componentType)
|
||||
.toBe(SomeComp);
|
||||
|
||||
expect(console.warnings).toEqual([
|
||||
`NgModule ${stringify(SomeModule)} uses ${stringify(SomeComp)} via "entryComponents" but it was neither declared nor imported! This warning will become an error after final.`
|
||||
]);
|
||||
});
|
||||
|
||||
it('should entryComponents ComponentFactories via ANALYZE_FOR_ENTRY_COMPONENTS', () => {
|
||||
@NgModule({
|
||||
declarations: [SomeComp],
|
||||
|
|
Loading…
Reference in New Issue