diff --git a/MIGRATION.md b/MIGRATION.md index 5022eefb59bd..d7c47af924b3 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -1044,7 +1044,11 @@ Starting in 7.0, we drop support for Angular < 14 #### Angular: Drop support for calling Storybook directly -In Storybook 6.4 we have deprecated calling Storybook directly (`npm run storybook`) for Angular. In Storybook 7.0, we've removed it entirely. Instead you have to set up the Storybook builder in your `angular.json` and execute `ng run :storybook` to start Storybook. Please visit https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular to set up Storybook for Angular correctly. +_Has automigration_ + +In Storybook 6.4 we deprecated calling Storybook directly (e.g. `npm run storybook`) for Angular. In Storybook 7.0, we've removed it entirely. Instead, you have to set up the Storybook builder in your `angular.json` and execute `ng run :storybook` to start Storybook. + +You can run `npx storybook@next automigrate` to automatically fix your configuration, or visit https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/README.md#how-do-i-migrate-to-an-angular-storybook-builder for instructions on how to set up Storybook for Angular manually. #### Angular: Application providers and ModuleWithProviders diff --git a/code/frameworks/angular/README.md b/code/frameworks/angular/README.md index 3158060f3f9a..d97e1ab93f2a 100644 --- a/code/frameworks/angular/README.md +++ b/code/frameworks/angular/README.md @@ -10,7 +10,7 @@ - [moduleMetadata decorator](#modulemetadata-decorator) - [applicationConfig decorator](#applicationconfig-decorator) - [FAQ](#faq) - - [How do I migrate to a Angular Storybook builder?](#how-do-i-migrate-to-a-angular-storybook-builder) + - [How do I migrate to an Angular Storybook builder?](#how-do-i-migrate-to-an-angular-storybook-builder) - [Do you have only one Angular project in your workspace?](#do-you-have-only-one-angular-project-in-your-workspace) - [Adjust your `package.json`](#adjust-your-packagejson) - [I have multiple projects in my Angular workspace](#i-have-multiple-projects-in-my-angular-workspace) @@ -252,10 +252,12 @@ export const WithCustomApplicationProvider: Story = { ## FAQ -### How do I migrate to a Angular Storybook builder? +### How do I migrate to an Angular Storybook builder? The Storybook [Angular builder](https://angular.io/guide/glossary#builder) is a new way to run Storybook in an Angular workspace. It is a drop-in replacement for running `storybook dev` and `storybook build` directly. +You can run `npx storybook@next automigrate` to try let Storybook detect and automatically fix your configuration. Otherwise, you can follow the next steps to manually adjust your configuration. + #### Do you have only one Angular project in your workspace? In this case go to your `angular.json` and add `storybook` and `build-storybook` entries in `architect` section of your project like shown above. diff --git a/code/frameworks/angular/src/server/framework-preset-angular-cli.ts b/code/frameworks/angular/src/server/framework-preset-angular-cli.ts index f8f78996c366..059d8b30f4d1 100644 --- a/code/frameworks/angular/src/server/framework-preset-angular-cli.ts +++ b/code/frameworks/angular/src/server/framework-preset-angular-cli.ts @@ -1,10 +1,10 @@ import webpack from 'webpack'; import { logger } from '@storybook/node-logger'; +import { AngularLegacyBuildOptionsError } from '@storybook/core-events/server-errors'; import { BuilderContext, targetFromTargetString } from '@angular-devkit/architect'; import { sync as findUpSync } from 'find-up'; -import { dedent } from 'ts-dedent'; - import { JsonObject, logging } from '@angular-devkit/core'; + import { getWebpackConfig as getCustomWebpackConfig } from './angular-cli-webpack'; import { moduleIsAvailable } from './utils/module-is-available'; import { PresetOptions } from './preset-options'; @@ -85,13 +85,6 @@ async function getBuilderOptions( return builderOptions; } -export const migrationToBuilderReferrenceMessage = dedent`Your Storybook startup uses a solution that is not supported. - You must use angular builder to have an explicit configuration on the project used in angular.json - Read more at: - - https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#sb-angular-builder) - - https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#angular13) - `; - /** * Checks if using legacy configuration that doesn't use builder and logs message referring to migration docs. */ @@ -101,7 +94,5 @@ function checkForLegacyBuildOptions(options: PresetOptions) { return; } - logger.error(migrationToBuilderReferrenceMessage); - - throw Error('angularBrowserTarget is undefined.'); + throw new AngularLegacyBuildOptionsError(); } diff --git a/code/lib/cli/src/automigrate/fixes/angular-builders.ts b/code/lib/cli/src/automigrate/fixes/angular-builders.ts index 626723f091ff..3bdc9da5062c 100644 --- a/code/lib/cli/src/automigrate/fixes/angular-builders.ts +++ b/code/lib/cli/src/automigrate/fixes/angular-builders.ts @@ -59,14 +59,14 @@ export const angularBuilders: Fix = { prompt() { return dedent` - We have detected that your project does not use the Storybook Angular builder yet. In Storybook 6.4 we have deprecated calling Storybook directly (npm run storybook) for Angular. In Storybook 7.0, we've removed it entirely. + We have detected that your project does not use the Storybook Angular builder yet. In Storybook 6.4 we deprecated calling Storybook directly (npm run storybook) for Angular. In Storybook 7.0, we've removed it entirely. In order to use the Storybook Angular builder, we need to add a few entries to your angular.json file. Additionally, we will add the @compodoc/compodoc package to your devDependencies if you want and we will add a few scripts to your package.json file. Also feel free to remove the Compodoc script from your package.json file if you don't use it apart from Storybook anymore. Storybook uses Compodoc internally and you don't have to call in separately anymore. Read more about the Angular builder here: ${chalk.yellow( - 'https://storybook.js.org/docs/angular/configure/storybook-builders' + 'https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular#how-do-i-migrate-to-an-angular-storybook-builder' )} `; }, diff --git a/code/lib/cli/src/generators/ANGULAR/helpers.ts b/code/lib/cli/src/generators/ANGULAR/helpers.ts index d1774e583017..b2394797909c 100644 --- a/code/lib/cli/src/generators/ANGULAR/helpers.ts +++ b/code/lib/cli/src/generators/ANGULAR/helpers.ts @@ -1,6 +1,8 @@ import fs from 'fs'; +import { join } from 'path'; import prompts from 'prompts'; import dedent from 'ts-dedent'; +import { MissingAngularJsonError } from '@storybook/core-events/server-errors'; export const ANGULAR_JSON_PATH = 'angular.json'; @@ -27,9 +29,7 @@ export class AngularJSON { constructor() { if (!fs.existsSync(ANGULAR_JSON_PATH)) { - throw new Error( - 'An angular.json file was not found in the current working directory. Storybook needs it to work properly, so please rerun the command at the root of your project, where the angular.json file is located. More info: https://storybook.js.org/docs/angular/faq#error-no-angularjson-file-found' - ); + throw new MissingAngularJsonError({ path: join(process.cwd(), ANGULAR_JSON_PATH) }); } const jsonContent = fs.readFileSync(ANGULAR_JSON_PATH, 'utf8'); diff --git a/code/lib/core-events/src/errors/preview-errors.ts b/code/lib/core-events/src/errors/preview-errors.ts index 3a2fe93aecf5..84161db505b8 100644 --- a/code/lib/core-events/src/errors/preview-errors.ts +++ b/code/lib/core-events/src/errors/preview-errors.ts @@ -19,25 +19,6 @@ export enum Category { PREVIEW_REACT_DOM_SHIM = 'PREVIEW_REACT-DOM-SHIM', PREVIEW_ROUTER = 'PREVIEW_ROUTER', PREVIEW_THEMING = 'PREVIEW_THEMING', - FRAMEWORK_ANGULAR = 'FRAMEWORK_ANGULAR', - FRAMEWORK_EMBER = 'FRAMEWORK_EMBER', - FRAMEWORK_HTML_VITE = 'FRAMEWORK_HTML-VITE', - FRAMEWORK_HTML_WEBPACK5 = 'FRAMEWORK_HTML-WEBPACK5', - FRAMEWORK_NEXTJS = 'FRAMEWORK_NEXTJS', - FRAMEWORK_PREACT_VITE = 'FRAMEWORK_PREACT-VITE', - FRAMEWORK_PREACT_WEBPACK5 = 'FRAMEWORK_PREACT-WEBPACK5', - FRAMEWORK_REACT_VITE = 'FRAMEWORK_REACT-VITE', - FRAMEWORK_REACT_WEBPACK5 = 'FRAMEWORK_REACT-WEBPACK5', - FRAMEWORK_SERVER_WEBPACK5 = 'FRAMEWORK_SERVER-WEBPACK5', - FRAMEWORK_SVELTE_VITE = 'FRAMEWORK_SVELTE-VITE', - FRAMEWORK_SVELTE_WEBPACK5 = 'FRAMEWORK_SVELTE-WEBPACK5', - FRAMEWORK_SVELTEKIT = 'FRAMEWORK_SVELTEKIT', - FRAMEWORK_VUE_VITE = 'FRAMEWORK_VUE-VITE', - FRAMEWORK_VUE_WEBPACK5 = 'FRAMEWORK_VUE-WEBPACK5', - FRAMEWORK_VUE3_VITE = 'FRAMEWORK_VUE3-VITE', - FRAMEWORK_VUE3_WEBPACK5 = 'FRAMEWORK_VUE3-WEBPACK5', - FRAMEWORK_WEB_COMPONENTS_VITE = 'FRAMEWORK_WEB-COMPONENTS-VITE', - FRAMEWORK_WEB_COMPONENTS_WEBPACK5 = 'FRAMEWORK_WEB-COMPONENTS-WEBPACK5', RENDERER_HTML = 'RENDERER_HTML', RENDERER_PREACT = 'RENDERER_PREACT', RENDERER_REACT = 'RENDERER_REACT', diff --git a/code/lib/core-events/src/errors/server-errors.ts b/code/lib/core-events/src/errors/server-errors.ts index bba1faec306f..f773a2fbf69e 100644 --- a/code/lib/core-events/src/errors/server-errors.ts +++ b/code/lib/core-events/src/errors/server-errors.ts @@ -28,6 +28,25 @@ export enum Category { POSTINSTALL = 'POSTINSTALL', DOCS_TOOLS = 'DOCS-TOOLS', CORE_WEBPACK = 'CORE-WEBPACK', + FRAMEWORK_ANGULAR = 'FRAMEWORK_ANGULAR', + FRAMEWORK_EMBER = 'FRAMEWORK_EMBER', + FRAMEWORK_HTML_VITE = 'FRAMEWORK_HTML-VITE', + FRAMEWORK_HTML_WEBPACK5 = 'FRAMEWORK_HTML-WEBPACK5', + FRAMEWORK_NEXTJS = 'FRAMEWORK_NEXTJS', + FRAMEWORK_PREACT_VITE = 'FRAMEWORK_PREACT-VITE', + FRAMEWORK_PREACT_WEBPACK5 = 'FRAMEWORK_PREACT-WEBPACK5', + FRAMEWORK_REACT_VITE = 'FRAMEWORK_REACT-VITE', + FRAMEWORK_REACT_WEBPACK5 = 'FRAMEWORK_REACT-WEBPACK5', + FRAMEWORK_SERVER_WEBPACK5 = 'FRAMEWORK_SERVER-WEBPACK5', + FRAMEWORK_SVELTE_VITE = 'FRAMEWORK_SVELTE-VITE', + FRAMEWORK_SVELTE_WEBPACK5 = 'FRAMEWORK_SVELTE-WEBPACK5', + FRAMEWORK_SVELTEKIT = 'FRAMEWORK_SVELTEKIT', + FRAMEWORK_VUE_VITE = 'FRAMEWORK_VUE-VITE', + FRAMEWORK_VUE_WEBPACK5 = 'FRAMEWORK_VUE-WEBPACK5', + FRAMEWORK_VUE3_VITE = 'FRAMEWORK_VUE3-VITE', + FRAMEWORK_VUE3_WEBPACK5 = 'FRAMEWORK_VUE3-WEBPACK5', + FRAMEWORK_WEB_COMPONENTS_VITE = 'FRAMEWORK_WEB-COMPONENTS-VITE', + FRAMEWORK_WEB_COMPONENTS_WEBPACK5 = 'FRAMEWORK_WEB-COMPONENTS-WEBPACK5', } export class NxProjectDetectedError extends StorybookError { @@ -216,3 +235,47 @@ export class WebpackCompilationError extends StorybookError { `; } } + +export class MissingAngularJsonError extends StorybookError { + readonly category = Category.CLI_INIT; + + readonly code = 2; + + public readonly documentation = + 'https://storybook.js.org/docs/angular/faq#error-no-angularjson-file-found'; + + constructor( + public data: { + path: string; + } + ) { + super(); + } + + template() { + return dedent` + An angular.json file was not found in the current working directory: ${this.data.path} + Storybook needs it to work properly, so please rerun the command at the root of your project, where the angular.json file is located. + `; + } +} + +export class AngularLegacyBuildOptionsError extends StorybookError { + readonly category = Category.FRAMEWORK_ANGULAR; + + readonly code = 1; + + public readonly documentation = [ + 'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#angular-drop-support-for-calling-storybook-directly', + 'https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular#how-do-i-migrate-to-an-angular-storybook-builder', + ]; + + template() { + return dedent` + Your Storybook startup script uses a solution that is not supported anymore. + You must use Angular builder to have an explicit configuration on the project used in angular.json. + + Please run 'npx storybook@next automigrate' to automatically fix your config. + `; + } +}