diff --git a/docs/generated/api-angular/generators/change-storybook-targets.md b/docs/generated/api-angular/generators/change-storybook-targets.md new file mode 100644 index 00000000000000..0cd843642695cf --- /dev/null +++ b/docs/generated/api-angular/generators/change-storybook-targets.md @@ -0,0 +1,28 @@ +--- +title: '@nrwl/angular:change-storybook-targets generator' +description: 'Change Storybook targets to use native Storybook builders' +--- + +# @nrwl/angular:change-storybook-targets + +Change Storybook targets to use native Storybook builders + +## Usage + +```bash +nx generate change-storybook-targets ... +``` + +By default, Nx will search for `change-storybook-targets` in the default collection provisioned in `workspace.json`. + +You can specify the collection explicitly as follows: + +```bash +nx g @nrwl/angular:change-storybook-targets ... +``` + +Show what will be generated without writing to disk: + +```bash +nx g change-storybook-targets ... --dry-run +``` diff --git a/docs/generated/api-storybook/generators/change-storybook-targets.md b/docs/generated/api-storybook/generators/change-storybook-targets.md new file mode 100644 index 00000000000000..64bbd2a44e4fb2 --- /dev/null +++ b/docs/generated/api-storybook/generators/change-storybook-targets.md @@ -0,0 +1,28 @@ +--- +title: '@nrwl/storybook:change-storybook-targets generator' +description: 'Change Storybook targets to use native Storybook builders' +--- + +# @nrwl/storybook:change-storybook-targets + +Change Storybook targets to use native Storybook builders + +## Usage + +```bash +nx generate change-storybook-targets ... +``` + +By default, Nx will search for `change-storybook-targets` in the default collection provisioned in `workspace.json`. + +You can specify the collection explicitly as follows: + +```bash +nx g @nrwl/storybook:change-storybook-targets ... +``` + +Show what will be generated without writing to disk: + +```bash +nx g change-storybook-targets ... --dry-run +``` diff --git a/docs/map.json b/docs/map.json index 0e893fde01e6a2..e4b80cb57d0673 100644 --- a/docs/map.json +++ b/docs/map.json @@ -739,6 +739,16 @@ "id": "storybook-migrate-stories-to-6-2", "file": "generated/api-angular/generators/storybook-migrate-stories-to-6-2" }, + { + "name": "change-storybook-targets generator", + "id": "change-storybook-targets", + "file": "generated/api-angular/generators/change-storybook-targets" + }, + { + "name": "change-storybook-targets generator", + "id": "change-storybook-targets", + "file": "generated/api-angular/generators/change-storybook-targets" + }, { "name": "upgrade-module generator", "id": "upgrade-module", @@ -938,7 +948,16 @@ "id": "migrate-stories-to-6-2", "file": "generated/api-storybook/generators/migrate-stories-to-6-2" }, - + { + "name": "change-storybook-targets generator", + "id": "change-storybook-targets", + "file": "generated/api-storybook/generators/change-storybook-targets" + }, + { + "name": "change-storybook-targets generator", + "id": "change-storybook-targets", + "file": "generated/api-storybook/generators/change-storybook-targets" + }, { "name": "Executors: Build", "id": "executors-build", diff --git a/packages/angular/generators.json b/packages/angular/generators.json index 57df82b7a1a36c..aafbfdbadb0ed7 100644 --- a/packages/angular/generators.json +++ b/packages/angular/generators.json @@ -145,6 +145,12 @@ "factory": "./src/generators/web-worker/compat", "schema": "./src/generators/web-worker/schema.json", "description": "Creates a Web Worker." + }, + "change-storybook-targets": { + "factory": "./src/generators/change-storybook-targets/compat", + "schema": "./src/generators/change-storybook-targets/schema.json", + "description": "Change Storybook targets to use native Storybook builders", + "hidden": false } }, "generators": { @@ -290,6 +296,11 @@ "factory": "./src/generators/web-worker/web-worker", "schema": "./src/generators/web-worker/schema.json", "description": "Creates a Web Worker." + }, + "change-storybook-targets": { + "factory": "./src/generators/change-storybook-targets/change-storybook-targets", + "schema": "./src/generators/change-storybook-targets/schema.json", + "description": "Change Storybook targets to use native Storybook builders" } } } diff --git a/packages/angular/generators.ts b/packages/angular/generators.ts index 4bce969fa262c4..3974cf25d31938 100644 --- a/packages/angular/generators.ts +++ b/packages/angular/generators.ts @@ -24,3 +24,4 @@ export * from './src/generators/component-cypress-spec/component-cypress-spec'; export * from './src/generators/component-story/component-story'; export * from './src/generators/web-worker/web-worker'; export * from './src/generators/mfe-remote/mfe-remote'; +export * from './src/generators/change-storybook-targets/change-storybook-targets'; diff --git a/packages/angular/src/generators/change-storybook-targets/change-storybook-targets.ts b/packages/angular/src/generators/change-storybook-targets/change-storybook-targets.ts new file mode 100644 index 00000000000000..a99e04ad65184e --- /dev/null +++ b/packages/angular/src/generators/change-storybook-targets/change-storybook-targets.ts @@ -0,0 +1,8 @@ +import type { Tree } from '@nrwl/devkit'; +import { changeStorybookTargetsGenerator } from '@nrwl/storybook'; + +export async function angularChangeStorybookTargestGenerator(tree: Tree) { + await changeStorybookTargetsGenerator(tree); +} + +export default angularChangeStorybookTargestGenerator; diff --git a/packages/angular/src/generators/change-storybook-targets/compat.ts b/packages/angular/src/generators/change-storybook-targets/compat.ts new file mode 100644 index 00000000000000..b00ad49789078b --- /dev/null +++ b/packages/angular/src/generators/change-storybook-targets/compat.ts @@ -0,0 +1,4 @@ +import { convertNxGenerator } from '@nrwl/devkit'; +import angularChangeStorybookTargestGenerator from './change-storybook-targets'; + +export default convertNxGenerator(angularChangeStorybookTargestGenerator); diff --git a/packages/angular/src/generators/change-storybook-targets/schema.json b/packages/angular/src/generators/change-storybook-targets/schema.json new file mode 100644 index 00000000000000..5cd3b03b359543 --- /dev/null +++ b/packages/angular/src/generators/change-storybook-targets/schema.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/schema", + "$id": "NxAngularChangeStorybookTargetsGenerator", + "type": "object", + "cli": "nx", + "properties": {}, + "additionalProperties": false, + "required": [] +} diff --git a/packages/storybook/generators.json b/packages/storybook/generators.json index bd22b5ca5b5ad6..a3f25fbdcfb47a 100644 --- a/packages/storybook/generators.json +++ b/packages/storybook/generators.json @@ -32,6 +32,12 @@ "schema": "./src/generators/migrate-stories-to-6-2/schema.json", "description": "Migrate stories syntax to 6.2", "hidden": false + }, + "change-storybook-targets": { + "factory": "./src/generators/change-storybook-targets/change-storybook-targets#changeStorybookTargetsSchematic", + "schema": "./src/generators/change-storybook-targets/schema.json", + "description": "Change Storybook targets to use native Storybook builders", + "hidden": false } }, "generators": { @@ -65,6 +71,12 @@ "schema": "./src/generators/migrate-stories-to-6-2/schema.json", "description": "Generate default Storybook configuration files using Storybook version >=6.x specs, for projects that already have Storybook instances and configurations of versions <6.x.", "hidden": false + }, + "change-storybook-targets": { + "factory": "./src/generators/change-storybook-targets/change-storybook-targets", + "schema": "./src/generators/change-storybook-targets/schema.json", + "description": "Change Storybook targets to use native Storybook builders", + "hidden": false } } } diff --git a/packages/storybook/index.ts b/packages/storybook/index.ts index f4d7843866269e..d00c2ff163f03b 100644 --- a/packages/storybook/index.ts +++ b/packages/storybook/index.ts @@ -2,4 +2,5 @@ export { configurationGenerator } from './src/generators/configuration/configura export { cypressProjectGenerator } from './src/generators/cypress-project/cypress-project'; export { migrateDefaultsGenerator } from './src/generators/migrate-defaults-5-to-6/migrate-defaults-5-to-6'; export { migrateStoriesTo62Generator } from './src/generators/migrate-stories-to-6-2/migrate-stories-to-6-2'; +export { changeStorybookTargetsGenerator } from './src/generators/change-storybook-targets/change-storybook-targets'; export { storybookVersion } from './src/utils/versions'; diff --git a/packages/storybook/migrations.json b/packages/storybook/migrations.json index 6fd6dd78b9b175..859f3dce1f3edc 100644 --- a/packages/storybook/migrations.json +++ b/packages/storybook/migrations.json @@ -78,6 +78,12 @@ "cli": "nx", "description": "Add projectBuildConfig option to project's Storybook config.", "factory": "./src/migrations/update-13-4-6/set-project-build-config" + }, + "update-14.0.0": { + "version": "14.0.0", + "cli": "nx", + "description": "Change Storybook targets to use native Storybook builders", + "factory": "./src/migrations/update-14-0-0/change-storybook-targets" } }, "packageJsonUpdates": { diff --git a/packages/storybook/src/migrations/update-14-0-0/__snapshots__/change-storybook-targets.spec.ts.snap b/packages/storybook/src/generators/change-storybook-targets/__snapshots__/change-storybook-targets.spec.ts.snap similarity index 100% rename from packages/storybook/src/migrations/update-14-0-0/__snapshots__/change-storybook-targets.spec.ts.snap rename to packages/storybook/src/generators/change-storybook-targets/__snapshots__/change-storybook-targets.spec.ts.snap diff --git a/packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.spec.ts b/packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.spec.ts similarity index 86% rename from packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.spec.ts rename to packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.spec.ts index 424592b540729a..e78af8e7c94697 100644 --- a/packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.spec.ts +++ b/packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.spec.ts @@ -1,7 +1,7 @@ import { Tree, writeJson } from '@nrwl/devkit'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { readWorkspace } from 'packages/devkit/src/generators/project-configuration'; -import changeStorybookTargets from './change-storybook-targets'; +import changeStorybookTargetsGenerator from './change-storybook-targets'; import * as defaultConfig from './test-configs/default-config.json'; import * as customNames from './test-configs/custom-names-config.json'; import * as nonAngular from './test-configs/non-angular.json'; @@ -17,19 +17,19 @@ describe('Change the Storybook targets for Angular projects to use native Storyb it(`should set the browserTarget correctly in the Storybook config according to the type of project`, async () => { writeJson(tree, 'workspace.json', defaultConfig); - await changeStorybookTargets(tree); + await changeStorybookTargetsGenerator(tree); expect(readWorkspace(tree)).toMatchSnapshot(); }); it(`should set the browserTarget correctly even if target names are not the default`, async () => { writeJson(tree, 'workspace.json', customNames); - await changeStorybookTargets(tree); + await changeStorybookTargetsGenerator(tree); expect(readWorkspace(tree)).toMatchSnapshot(); }); it(`should keep any extra options added in the target`, async () => { writeJson(tree, 'workspace.json', extraOptions); - await changeStorybookTargets(tree); + await changeStorybookTargetsGenerator(tree); expect(readWorkspace(tree)).toMatchSnapshot(); }); }); @@ -41,7 +41,7 @@ describe('Change the Storybook targets for Angular projects to use native Storyb }); it(`should not change their Storybook targets`, async () => { - await changeStorybookTargets(tree); + await changeStorybookTargetsGenerator(tree); expect(readWorkspace(tree)).toMatchSnapshot(); }); }); diff --git a/packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.ts b/packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.ts new file mode 100644 index 00000000000000..d78d3fd6b220dd --- /dev/null +++ b/packages/storybook/src/generators/change-storybook-targets/change-storybook-targets.ts @@ -0,0 +1,166 @@ +import { + logger, + Tree, + formatFiles, + updateProjectConfiguration, + getProjects, + TargetConfiguration, + ProjectConfiguration, + Target, + convertNxGenerator, +} from '@nrwl/devkit'; +import { findStorybookAndBuildTargets } from '../../utils/utilities'; + +export async function changeStorybookTargetsGenerator(tree: Tree) { + let changesMade = false; + let changesMadeToAtLeastOne = false; + const projects = getProjects(tree); + [...projects.entries()].forEach(([projectName, projectConfiguration]) => { + changesMade = false; + const { storybookBuildTarget, storybookTarget, buildTarget } = + findStorybookAndBuildTargets(projectConfiguration.targets); + if ( + projectName && + storybookTarget && + projectConfiguration?.targets?.[storybookTarget]?.options?.uiFramework === + '@storybook/angular' + ) { + projectConfiguration.targets[storybookTarget] = updateStorybookTarget( + projectConfiguration, + storybookTarget, + projectName, + buildTarget, + storybookBuildTarget + ); + changesMade = true; + changesMadeToAtLeastOne = true; + projectConfiguration.targets[storybookBuildTarget] = + updateStorybookBuildTarget( + projectConfiguration, + projectName, + buildTarget, + storybookBuildTarget + ); + } else { + logger.warn(`Could not find a Storybook target for ${projectName}.`); + } + if (changesMade) { + updateProjectConfiguration(tree, projectName, projectConfiguration); + } + }); + + if (changesMadeToAtLeastOne) { + await formatFiles(tree); + } +} + +function updateStorybookTarget( + projectConfiguration: ProjectConfiguration, + storybookTarget: string, + projectName: string, + buildTarget: string, + storybookBuildTarget: string +): TargetConfiguration { + const oldStorybookTargetConfig: TargetConfiguration = + projectConfiguration?.targets?.[storybookTarget]; + const newStorybookTargetConfig: TargetConfiguration = { + executor: '@storybook/angular:start-storybook', + options: { + port: oldStorybookTargetConfig.options.port, + configDir: oldStorybookTargetConfig.options.config?.configFolder, + browserTarget: undefined, + compodoc: false, + }, + configurations: oldStorybookTargetConfig.configurations, + }; + + const { project, target } = parseTargetStringCustom( + oldStorybookTargetConfig.options.projectBuildConfig + ); + if (project && target) { + newStorybookTargetConfig.options.browserTarget = + oldStorybookTargetConfig.options.projectBuildConfig; + } else { + newStorybookTargetConfig.options.browserTarget = `${projectName}:${ + buildTarget ? buildTarget : storybookBuildTarget + }`; + } + + const { + uiFramework, + outputPath, + config, + projectBuildConfig, + ...optionsToCopy + } = oldStorybookTargetConfig.options; + + newStorybookTargetConfig.options = { + ...optionsToCopy, + ...newStorybookTargetConfig.options, + }; + + return newStorybookTargetConfig; +} + +function updateStorybookBuildTarget( + projectConfiguration: ProjectConfiguration, + projectName: string, + buildTarget: string, + storybookBuildTarget: string +): TargetConfiguration { + const oldStorybookBuildTargetConfig: TargetConfiguration = + projectConfiguration?.targets?.[storybookBuildTarget]; + const newStorybookBuildTargetConfig: TargetConfiguration = { + executor: '@storybook/angular:build-storybook', + outputs: oldStorybookBuildTargetConfig.outputs, + options: { + outputDir: oldStorybookBuildTargetConfig.options.outputPath, + configDir: oldStorybookBuildTargetConfig.options.config?.configFolder, + browserTarget: undefined, + compodoc: false, + }, + configurations: oldStorybookBuildTargetConfig.configurations, + }; + + const { project, target } = parseTargetStringCustom( + oldStorybookBuildTargetConfig.options.projectBuildConfig + ); + if (project && target) { + newStorybookBuildTargetConfig.options.browserTarget = + oldStorybookBuildTargetConfig.options.projectBuildConfig; + } else { + newStorybookBuildTargetConfig.options.browserTarget = `${projectName}:${ + buildTarget ? buildTarget : storybookBuildTarget + }`; + } + + const { + uiFramework, + outputPath, + config, + projectBuildConfig, + ...optionsToCopy + } = oldStorybookBuildTargetConfig.options; + + newStorybookBuildTargetConfig.options = { + ...optionsToCopy, + ...newStorybookBuildTargetConfig.options, + }; + + return newStorybookBuildTargetConfig; +} + +function parseTargetStringCustom(targetString: string): Target { + const [project, target, configuration] = targetString.split(':'); + + return { + project, + target, + configuration, + }; +} + +export default changeStorybookTargetsGenerator; +export const changeStorybookTargetsSchematic = convertNxGenerator( + changeStorybookTargetsGenerator +); diff --git a/packages/storybook/src/generators/change-storybook-targets/schema.d.ts b/packages/storybook/src/generators/change-storybook-targets/schema.d.ts new file mode 100644 index 00000000000000..0d9cdac014503c --- /dev/null +++ b/packages/storybook/src/generators/change-storybook-targets/schema.d.ts @@ -0,0 +1 @@ +export interface ChangeStorybookTargets {} diff --git a/packages/storybook/src/generators/change-storybook-targets/schema.json b/packages/storybook/src/generators/change-storybook-targets/schema.json new file mode 100644 index 00000000000000..d26389576f6f10 --- /dev/null +++ b/packages/storybook/src/generators/change-storybook-targets/schema.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/schema", + "cli": "nx", + "$id": "change-storybook-targets", + "type": "object", + "properties": {}, + "required": [] +} diff --git a/packages/storybook/src/migrations/update-14-0-0/test-configs/custom-names-config.json b/packages/storybook/src/generators/change-storybook-targets/test-configs/custom-names-config.json similarity index 100% rename from packages/storybook/src/migrations/update-14-0-0/test-configs/custom-names-config.json rename to packages/storybook/src/generators/change-storybook-targets/test-configs/custom-names-config.json diff --git a/packages/storybook/src/migrations/update-14-0-0/test-configs/default-config.json b/packages/storybook/src/generators/change-storybook-targets/test-configs/default-config.json similarity index 100% rename from packages/storybook/src/migrations/update-14-0-0/test-configs/default-config.json rename to packages/storybook/src/generators/change-storybook-targets/test-configs/default-config.json diff --git a/packages/storybook/src/migrations/update-14-0-0/test-configs/extra-options-for-storybook.json b/packages/storybook/src/generators/change-storybook-targets/test-configs/extra-options-for-storybook.json similarity index 100% rename from packages/storybook/src/migrations/update-14-0-0/test-configs/extra-options-for-storybook.json rename to packages/storybook/src/generators/change-storybook-targets/test-configs/extra-options-for-storybook.json diff --git a/packages/storybook/src/migrations/update-14-0-0/test-configs/non-angular.json b/packages/storybook/src/generators/change-storybook-targets/test-configs/non-angular.json similarity index 100% rename from packages/storybook/src/migrations/update-14-0-0/test-configs/non-angular.json rename to packages/storybook/src/generators/change-storybook-targets/test-configs/non-angular.json diff --git a/packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.ts b/packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.ts index 0d4acc664e396b..8ae413e3d013b1 100644 --- a/packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.ts +++ b/packages/storybook/src/migrations/update-14-0-0/change-storybook-targets.ts @@ -1,160 +1,6 @@ -import { - logger, - Tree, - formatFiles, - updateProjectConfiguration, - getProjects, - TargetConfiguration, - ProjectConfiguration, - Target, -} from '@nrwl/devkit'; -import { findStorybookAndBuildTargets } from '../../utils/utilities'; +import { Tree } from '@nrwl/devkit'; +import { changeStorybookTargetsGenerator } from '../../generators/change-storybook-targets/change-storybook-targets'; export default async function changeStorybookTargets(tree: Tree) { - let changesMade = false; - let changesMadeToAtLeastOne = false; - const projects = getProjects(tree); - [...projects.entries()].forEach(([projectName, projectConfiguration]) => { - changesMade = false; - const { storybookBuildTarget, storybookTarget, buildTarget } = - findStorybookAndBuildTargets(projectConfiguration.targets); - if ( - projectName && - storybookTarget && - projectConfiguration?.targets?.[storybookTarget]?.options?.uiFramework === - '@storybook/angular' - ) { - projectConfiguration.targets[storybookTarget] = updateStorybookTarget( - projectConfiguration, - storybookTarget, - projectName, - buildTarget, - storybookBuildTarget - ); - changesMade = true; - changesMadeToAtLeastOne = true; - projectConfiguration.targets[storybookBuildTarget] = - updateStorybookBuildTarget( - projectConfiguration, - projectName, - buildTarget, - storybookBuildTarget - ); - } else { - logger.warn(`Could not find a Storybook target for ${projectName}.`); - } - if (changesMade) { - updateProjectConfiguration(tree, projectName, projectConfiguration); - } - }); - - if (changesMadeToAtLeastOne) { - await formatFiles(tree); - } -} - -function updateStorybookTarget( - projectConfiguration: ProjectConfiguration, - storybookTarget: string, - projectName: string, - buildTarget: string, - storybookBuildTarget: string -): TargetConfiguration { - const oldStorybookTargetConfig: TargetConfiguration = - projectConfiguration?.targets?.[storybookTarget]; - const newStorybookTargetConfig: TargetConfiguration = { - executor: '@storybook/angular:start-storybook', - options: { - port: oldStorybookTargetConfig.options.port, - configDir: oldStorybookTargetConfig.options.config?.configFolder, - browserTarget: undefined, - compodoc: false, - }, - configurations: oldStorybookTargetConfig.configurations, - }; - - const { project, target } = parseTargetStringCustom( - oldStorybookTargetConfig.options.projectBuildConfig - ); - if (project && target) { - newStorybookTargetConfig.options.browserTarget = - oldStorybookTargetConfig.options.projectBuildConfig; - } else { - newStorybookTargetConfig.options.browserTarget = `${projectName}:${ - buildTarget ? buildTarget : storybookBuildTarget - }`; - } - - const { - uiFramework, - outputPath, - config, - projectBuildConfig, - ...optionsToCopy - } = oldStorybookTargetConfig.options; - - newStorybookTargetConfig.options = { - ...optionsToCopy, - ...newStorybookTargetConfig.options, - }; - - return newStorybookTargetConfig; -} - -function updateStorybookBuildTarget( - projectConfiguration: ProjectConfiguration, - projectName: string, - buildTarget: string, - storybookBuildTarget: string -): TargetConfiguration { - const oldStorybookBuildTargetConfig: TargetConfiguration = - projectConfiguration?.targets?.[storybookBuildTarget]; - const newStorybookBuildTargetConfig: TargetConfiguration = { - executor: '@storybook/angular:build-storybook', - outputs: oldStorybookBuildTargetConfig.outputs, - options: { - outputDir: oldStorybookBuildTargetConfig.options.outputPath, - configDir: oldStorybookBuildTargetConfig.options.config?.configFolder, - browserTarget: undefined, - compodoc: false, - }, - configurations: oldStorybookBuildTargetConfig.configurations, - }; - - const { project, target } = parseTargetStringCustom( - oldStorybookBuildTargetConfig.options.projectBuildConfig - ); - if (project && target) { - newStorybookBuildTargetConfig.options.browserTarget = - oldStorybookBuildTargetConfig.options.projectBuildConfig; - } else { - newStorybookBuildTargetConfig.options.browserTarget = `${projectName}:${ - buildTarget ? buildTarget : storybookBuildTarget - }`; - } - - const { - uiFramework, - outputPath, - config, - projectBuildConfig, - ...optionsToCopy - } = oldStorybookBuildTargetConfig.options; - - newStorybookBuildTargetConfig.options = { - ...optionsToCopy, - ...newStorybookBuildTargetConfig.options, - }; - - return newStorybookBuildTargetConfig; -} - -export function parseTargetStringCustom(targetString: string): Target { - const [project, target, configuration] = targetString.split(':'); - - return { - project, - target, - configuration, - }; + return changeStorybookTargetsGenerator(tree); }