diff --git a/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts b/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts index 1109fba33a93..78ae11b187b4 100644 --- a/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts +++ b/src/cdk/schematics/ng-generate/drag-drop/index.spec.ts @@ -46,6 +46,19 @@ describe('CDK drag-drop schematic', () => { expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.scss'); }); + it('should not generate invalid stylesheets', () => { + const tree = runner.runSchematic( + 'drag-drop', {styleext: 'styl', ...baseOptions}, createTestApp(runner)); + + // In this case we expect the schematic to generate a plain "css" file because + // the component schematics are using CSS style templates which are not compatible + // with all CLI supported styles (e.g. Stylus or Sass) + expect(tree.files).toContain('/projects/material/src/app/foo/foo.component.css', + 'Expected the schematic to generate a plain "css" file.'); + expect(tree.files).not.toContain('/projects/material/src/app/foo/foo.component.styl', + 'Expected the schematic to not generate a "stylus" file'); + }); + it('should fall back to the @schematics/angular:component option value', () => { const tree = runner.runSchematic( 'drag-drop', baseOptions, createTestApp(runner, {style: 'less'})); diff --git a/src/cdk/schematics/utils/build-component.ts b/src/cdk/schematics/utils/build-component.ts index 71c547c3843a..83fa3eba582f 100644 --- a/src/cdk/schematics/utils/build-component.ts +++ b/src/cdk/schematics/utils/build-component.ts @@ -40,6 +40,12 @@ import {getProjectFromWorkspace} from './get-project'; import {getDefaultComponentOptions} from './schematic-options'; import {ts} from './version-agnostic-typescript'; +/** + * List of style extensions which are CSS compatible. All supported CLI style extensions can be + * found here: angular/angular-cli/master/packages/schematics/angular/ng-new/schema.json#L118-L122 + */ +const supportedCssExtensions = ['css', 'scss', 'less']; + function readIntoSourceFile(host: Tree, modulePath: string) { const text = host.read(modulePath); if (text === null) { @@ -195,6 +201,14 @@ export function buildComponent(options: ComponentOptions, validateName(options.name); validateHtmlSelector(options.selector!); + // In case the specified style extension is not part of the supported CSS supersets, + // we generate the stylesheets with the "css" extension. This ensures that we don't + // accidentally generate invalid stylesheets (e.g. drag-drop-comp.styl) which will + // break the Angular CLI project. See: https://github.com/angular/material2/issues/15164 + if (!supportedCssExtensions.includes(options.styleext!)) { + options.styleext = 'css'; + } + // Object that will be used as context for the EJS templates. const baseTemplateContext = { ...strings,