diff --git a/src/material/schematics/BUILD.bazel b/src/material/schematics/BUILD.bazel index 7edc88de61f2..c13243d92f49 100644 --- a/src/material/schematics/BUILD.bazel +++ b/src/material/schematics/BUILD.bazel @@ -48,6 +48,7 @@ ts_library( # TODO(devversion): Only include jasmine for test sources (See: tsconfig types). "@npm//@types/jasmine", "@npm//@types/node", + "@npm//rxjs", "@npm//tslint", "@npm//typescript", ], diff --git a/src/material/schematics/ng-add/setup-project.ts b/src/material/schematics/ng-add/setup-project.ts index e3ec2e8a0906..8c43145dd495 100644 --- a/src/material/schematics/ng-add/setup-project.ts +++ b/src/material/schematics/ng-add/setup-project.ts @@ -6,11 +6,13 @@ * found in the LICENSE file at https://angular.io/license */ -import {chain, noop, Rule, SchematicContext, Tree} from '@angular-devkit/schematics'; +import {chain, noop, Rule, SchematicContext, Tree, callRule} from '@angular-devkit/schematics'; import {getProjectFromWorkspace, getProjectStyleFile} from '@angular/cdk/schematics'; import {getWorkspace} from '@schematics/angular/utility/workspace'; import {addRootProvider} from '@schematics/angular/utility'; import {ProjectType} from '@schematics/angular/utility/workspace-models'; +import {of as observableOf} from 'rxjs'; +import {catchError} from 'rxjs/operators'; import {addFontsToIndex} from './fonts/material-fonts'; import {Schema} from './schema'; import {addThemeToAppStyles, addTypographyClass} from './theming/theming'; @@ -28,14 +30,7 @@ export default function (options: Schema): Rule { if (project.extensions['projectType'] === ProjectType.Application) { return chain([ - options.animations === 'excluded' - ? noop() - : addRootProvider(options.project, ({code, external}) => { - return code`${external( - 'provideAnimationsAsync', - '@angular/platform-browser/animations/async', - )}(${options.animations === 'disabled' ? `'noop'` : ''})`; - }), + addAnimations(options), addThemeToAppStyles(options), addFontsToIndex(options), addMaterialAppStyles(options), @@ -96,3 +91,32 @@ function addMaterialAppStyles(options: Schema) { host.commitUpdate(recorder); }; } + +/** Adds the animations package to the project based on the conffiguration. */ +function addAnimations(options: Schema): Rule { + return (host: Tree, context: SchematicContext) => { + const animationsRule = + options.animations === 'excluded' + ? noop() + : addRootProvider(options.project, ({code, external}) => { + return code`${external( + 'provideAnimationsAsync', + '@angular/platform-browser/animations/async', + )}(${options.animations === 'disabled' ? `'noop'` : ''})`; + }); + + // The `addRootProvider` rule can throw in some custom scenarios (see #28640). + // Add some error handling around it so the setup isn't interrupted. + return callRule(animationsRule, host, context).pipe( + catchError(() => { + context.logger.error( + 'Failed to add animations to project. Continuing with the Angular Material setup.', + ); + context.logger.info( + 'Read more about setting up the animations manually: https://angular.io/guide/animations', + ); + return observableOf(host); + }), + ); + }; +}