Skip to content

Commit

Permalink
refactor(core): static-query template strategy should not parse style…
Browse files Browse the repository at this point in the history
…sheets (#29876)

Currently the `template-strategy` for the static query migration uses the
Angular compiler in order to determine the query timing. This is problematic
as the AngularCompilerProgram also collects metadata for referenced
component stylesheets which aren't necessarily present. e.g. in a CLI
project the component can reference a Sass file. It's not guaranteed
that the standalone Angular compiler plugin supports Sass without
custom logic that is brought in by the Angular CLI webpack plugin.

In order to avoid any failures for invalid stylesheets, we just disable
normalizing of all referenced stylesheets.

PR Close #29876
  • Loading branch information
devversion authored and benlesh committed Apr 19, 2019
1 parent ca59164 commit c1d5fbd
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {AotCompiler, CompileDirectiveMetadata, CompileMetadataResolver, CompileNgModuleMetadata, NgAnalyzedModules, StaticSymbol, TemplateAst, findStaticQueryIds, staticViewQueryIds} from '@angular/compiler';
import {AotCompiler, CompileDirectiveMetadata, CompileMetadataResolver, CompileNgModuleMetadata, CompileStylesheetMetadata, NgAnalyzedModules, StaticSymbol, TemplateAst, findStaticQueryIds, staticViewQueryIds} from '@angular/compiler';
import {Diagnostic, createProgram, readConfiguration} from '@angular/compiler-cli';
import {resolve} from 'path';
import * as ts from 'typescript';
Expand Down Expand Up @@ -41,6 +41,20 @@ export class QueryTemplateStrategy implements TimingStrategy {
// this by just accessing the necessary private properties using the bracket notation.
this.compiler = (aotProgram as any)['compiler'];
this.metadataResolver = this.compiler !['_metadataResolver'];

// Modify the "DirectiveNormalizer" to not normalize any referenced external stylesheets.
// This is necessary because in CLI projects preprocessor files are commonly referenced
// and we don't want to parse them in order to extract relative style references. This
// breaks the analysis of the project because we instantiate a standalone AOT compiler
// program which does not contain the custom logic by the Angular CLI Webpack compiler plugin.
const directiveNormalizer = this.metadataResolver !['_directiveNormalizer'];
directiveNormalizer['_normalizeStylesheet'] = function(metadata: CompileStylesheetMetadata) {
return new CompileStylesheetMetadata(
{styles: metadata.styles, styleUrls: [], moduleUrl: metadata.moduleUrl !});
};

// Retrieves the analyzed modules of the current program. This data can be
// used to determine the timing for registered queries.
const analyzedModules = (aotProgram as any)['analyzedModules'] as NgAnalyzedModules;

const ngDiagnostics = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,5 +488,32 @@ describe('static-queries migration with template strategy', () => {
expect(warnOutput[0])
.toMatch(/^⮑ {3}index.ts@6:11: Content queries cannot be migrated automatically\./);
});

it('should not normalize stylesheets which are referenced in component', async() => {
writeFile('sub_dir/index.ts', `
import {Component, NgModule, ContentChild} from '@angular/core';
@Component({
template: '<p #myRef></p>',
styleUrls: ['./my-comp.scss']
})
export class MyComp {}
@NgModule({declarations: [MyComp]})
export class MyModule {}
`);

// In order to check that the stylesheet is not normalized, we add an "@import" statement
// that would be extracted by the "DirectiveNormalizer" and fail because the URL resolver
// is not able to resolve the "../shared" relative import to the SCSS file extension.
writeFile('/sub_dir/my-comp.scss', `@import '../shared'`);
writeFile('/shared.scss', `shared {}`);

spyOn(console, 'error').and.callThrough();

await runMigration();

expect(console.error).toHaveBeenCalledTimes(0);
});
});
});

0 comments on commit c1d5fbd

Please sign in to comment.