feat(ivy): support styleUrls in ngtsc (#27357)
This commit adds support for resolution of styleUrls to ngtsc. Previously this field was never read, and so components with styleUrls would appear unstyled after compilation. PR Close #27357
This commit is contained in:
parent
b5ed403bc4
commit
cfb67edd85
|
@ -57,6 +57,7 @@ export class ComponentDecoratorHandler implements
|
|||
preanalyze(node: ts.ClassDeclaration, decorator: Decorator): Promise<void>|undefined {
|
||||
const meta = this._resolveLiteral(decorator);
|
||||
const component = reflectObjectLiteral(meta);
|
||||
const promises: Promise<void>[] = [];
|
||||
|
||||
if (this.resourceLoader.preload !== undefined && component.has('templateUrl')) {
|
||||
const templateUrlExpr = component.get('templateUrl') !;
|
||||
|
@ -66,9 +67,27 @@ export class ComponentDecoratorHandler implements
|
|||
ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string');
|
||||
}
|
||||
const url = path.posix.resolve(path.dirname(node.getSourceFile().fileName), templateUrl);
|
||||
return this.resourceLoader.preload(url);
|
||||
const promise = this.resourceLoader.preload(url);
|
||||
if (promise !== undefined) {
|
||||
promises.push(promise);
|
||||
}
|
||||
}
|
||||
|
||||
const styleUrls = this._extractStyleUrls(component);
|
||||
if (this.resourceLoader.preload !== undefined && styleUrls !== null) {
|
||||
for (const styleUrl of styleUrls) {
|
||||
const url = path.posix.resolve(path.dirname(node.getSourceFile().fileName), styleUrl);
|
||||
const promise = this.resourceLoader.preload(url);
|
||||
if (promise !== undefined) {
|
||||
promises.push(promise);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (promises.length !== 0) {
|
||||
return Promise.all(promises).then(() => undefined);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<ComponentHandlerData> {
|
||||
|
@ -186,6 +205,14 @@ export class ComponentDecoratorHandler implements
|
|||
styles = parseFieldArrayValue(component, 'styles', this.reflector, this.checker);
|
||||
}
|
||||
|
||||
let styleUrls = this._extractStyleUrls(component);
|
||||
if (styleUrls !== null) {
|
||||
if (styles === null) {
|
||||
styles = [];
|
||||
}
|
||||
styles.push(...styleUrls.map(styleUrl => this.resourceLoader.load(styleUrl)));
|
||||
}
|
||||
|
||||
let encapsulation: number = 0;
|
||||
if (component.has('encapsulation')) {
|
||||
encapsulation = parseInt(staticallyResolve(
|
||||
|
@ -282,4 +309,18 @@ export class ComponentDecoratorHandler implements
|
|||
this.literalCache.set(decorator, meta);
|
||||
return meta;
|
||||
}
|
||||
|
||||
private _extractStyleUrls(component: Map<string, ts.Expression>): string[]|null {
|
||||
if (!component.has('styleUrls')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const styleUrlsExpr = component.get('styleUrls') !;
|
||||
const styleUrls = staticallyResolve(styleUrlsExpr, this.reflector, this.checker);
|
||||
if (!Array.isArray(styleUrls) || !styleUrls.every(url => typeof url === 'string')) {
|
||||
throw new FatalDiagnosticError(
|
||||
ErrorCode.VALUE_HAS_WRONG_TYPE, styleUrlsExpr, 'styleUrls must be an array of strings');
|
||||
}
|
||||
return styleUrls as string[];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,26 @@ describe('ngtsc behavioral tests', () => {
|
|||
expect(jsContents).toContain('Hello World');
|
||||
});
|
||||
|
||||
it('should compile components with styleUrls', () => {
|
||||
env.tsconfig();
|
||||
env.write('test.ts', `
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
styleUrls: ['./dir/style.css'],
|
||||
template: '',
|
||||
})
|
||||
export class TestCmp {}
|
||||
`);
|
||||
env.write('dir/style.css', ':host { background-color: blue; }');
|
||||
|
||||
env.driveMain();
|
||||
|
||||
const jsContents = env.getContents('test.js');
|
||||
expect(jsContents).toContain('background-color: blue');
|
||||
});
|
||||
|
||||
it('should compile NgModules without errors', () => {
|
||||
env.tsconfig();
|
||||
env.write('test.ts', `
|
||||
|
|
Loading…
Reference in New Issue