From c46aa084f53be7ebdb8cc450bd81907222d00275 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 30 Apr 2024 15:40:15 -0400 Subject: [PATCH] fix(@schematics/angular): add postcss dependency in application migration if needed The application migration schematic will now attempt to detect the usage of custom postcss plugins within a workspace and install the `postcss` dependency if required. This will only occur if the migration analysis allows for the conversion to use the `@angular/build` package instead of the `@angular-devkit/build-angular` package. Custom postcss configurations will be detected within the same locations as the build system itself which includes the workspace root and any project root for the `postcss.config.json` and `.postcssrc.json` files. (cherry picked from commit 511d876fb7513b5537f2d086b2583005f8684342) --- .../use-application-builder/migration.ts | 38 ++++++++++++++++++ .../use-application-builder/migration_spec.ts | 40 ++++++++++++++++++- .../utility/latest-versions/package.json | 1 + 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/migrations/use-application-builder/migration.ts b/packages/schematics/angular/migrations/use-application-builder/migration.ts index c66908231a05..74087dab86ab 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration.ts @@ -27,6 +27,7 @@ import { JSONFile } from '../../utility/json-file'; import { latestVersions } from '../../utility/latest-versions'; import { TargetDefinition, + WorkspaceDefinition, allTargetOptions, allWorkspaceTargets, updateWorkspace, @@ -265,6 +266,18 @@ function updateProjects(tree: Tree, context: SchematicContext) { }), ); } + + // Add postcss dependency if any projects have a custom postcss configuration file. + // The build system only supports files in a project root or workspace root with + // names of either 'postcss.config.json' or '.postcssrc.json'. + if (hasPostcssConfiguration(tree, workspace)) { + rules.push( + addDependency('postcss', latestVersions['postcss'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Replace, + }), + ); + } } return chain(rules); @@ -297,6 +310,31 @@ function hasLessStylesheets(tree: Tree) { } } +/** + * Searches for a Postcss configuration file within the workspace root + * or any of the project roots. + * + * @param tree A Schematics tree instance to search + * @param workspace A Workspace to check for projects + * @returns true, if a Postcss configuration file is found; otherwise, false + */ +function hasPostcssConfiguration(tree: Tree, workspace: WorkspaceDefinition) { + // Add workspace root + const searchDirectories = ['']; + + // Add each project root + for (const { root } of workspace.projects.values()) { + if (root) { + searchDirectories.push(root); + } + } + + return searchDirectories.some( + (dir) => + tree.exists(join(dir, 'postcss.config.json')) || tree.exists(join(dir, '.postcssrc.json')), + ); +} + function* visit( directory: DirEntry, ): IterableIterator<[fileName: string, contents: string, sass: boolean]> { diff --git a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts index d0d20348e600..6bebff64bb80 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts @@ -278,11 +278,49 @@ describe(`Migration to use the application builder`, () => { expect(devDependencies['less']).toBeDefined(); }); - it('should not add "less" dependency when converting to "@angular/build" and a ".less" file is present', async () => { + it('should not add "less" dependency when converting to "@angular/build" and a ".less" file is not present', async () => { const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); const { devDependencies } = JSON.parse(newTree.readContent('/package.json')); expect(devDependencies['less']).toBeUndefined(); }); + + it('should add "postcss" dependency when converting to "@angular/build" and postcss.config.json is present', async () => { + tree.create('postcss.config.json', '{}'); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + + const { devDependencies } = JSON.parse(newTree.readContent('/package.json')); + + expect(devDependencies['postcss']).toBeDefined(); + }); + + it('should add "postcss" dependency when converting to "@angular/build" and .postcssrc.json is present', async () => { + tree.create('.postcssrc.json', '{}'); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + + const { devDependencies } = JSON.parse(newTree.readContent('/package.json')); + + expect(devDependencies['postcss']).toBeDefined(); + }); + + it('should add "postcss" dependency when converting to "@angular/build" and .postcssrc.json is present in project', async () => { + tree.create('/project/app/.postcssrc.json', '{}'); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + + const { devDependencies } = JSON.parse(newTree.readContent('/package.json')); + + expect(devDependencies['postcss']).toBeDefined(); + }); + + it('should not add "postcss" dependency when converting to "@angular/build" and a Postcss configuration is not present', async () => { + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + + const { devDependencies } = JSON.parse(newTree.readContent('/package.json')); + + expect(devDependencies['postcss']).toBeUndefined(); + }); }); diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index f9b29642dce8..847f1acf5f41 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -18,6 +18,7 @@ "karma": "~6.4.0", "less": "^4.2.0", "ng-packagr": "^18.0.0-next.0", + "postcss": "^8.4.38", "protractor": "~7.0.0", "rxjs": "~7.8.0", "tslib": "^2.3.0",