Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Deprecate storyStoreV6 (including storiesOf) and storyIndexers #23938

Merged
merged 13 commits into from
Oct 3, 2023
Merged
90 changes: 80 additions & 10 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<h1>Migration</h1>

- [From version 7.4.0 to 7.5.0](#from-version-740-to-750)
- [`storyStoreV6` and `storiesOf` is deprecated](#storystorev6-and-storiesof-is-deprecated)
- [`storyIndexers` is replaced with `experimental_indexers`](#storyindexers-is-replaced-with-experimental_indexers)
- [From version 7.0.0 to 7.2.0](#from-version-700-to-720)
- [Addon API is more type-strict](#addon-api-is-more-type-strict)
- [Addon API is more type-strict](#addon-api-is-more-type-strict)
- [From version 6.5.x to 7.0.0](#from-version-65x-to-700)
- [7.0 breaking changes](#70-breaking-changes)
- [Dropped support for Node 15 and below](#dropped-support-for-node-15-and-below)
Expand All @@ -27,7 +30,7 @@
- [Deploying build artifacts](#deploying-build-artifacts)
- [Dropped support for file URLs](#dropped-support-for-file-urls)
- [Serving with nginx](#serving-with-nginx)
- [Ignore story files from node\_modules](#ignore-story-files-from-node_modules)
- [Ignore story files from node_modules](#ignore-story-files-from-node_modules)
- [7.0 Core changes](#70-core-changes)
- [7.0 feature flags removed](#70-feature-flags-removed)
- [Story context is prepared before for supporting fine grained updates](#story-context-is-prepared-before-for-supporting-fine-grained-updates)
Expand All @@ -39,7 +42,7 @@
- [Addon-interactions: Interactions debugger is now default](#addon-interactions-interactions-debugger-is-now-default)
- [7.0 Vite changes](#70-vite-changes)
- [Vite builder uses Vite config automatically](#vite-builder-uses-vite-config-automatically)
- [Vite cache moved to node\_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
- [Vite cache moved to node_modules/.cache/.vite-storybook](#vite-cache-moved-to-node_modulescachevite-storybook)
- [7.0 Webpack changes](#70-webpack-changes)
- [Webpack4 support discontinued](#webpack4-support-discontinued)
- [Babel mode v7 exclusively](#babel-mode-v7-exclusively)
Expand Down Expand Up @@ -89,7 +92,7 @@
- [Dropped addon-docs manual babel configuration](#dropped-addon-docs-manual-babel-configuration)
- [Dropped addon-docs manual configuration](#dropped-addon-docs-manual-configuration)
- [Autoplay in docs](#autoplay-in-docs)
- [Removed STORYBOOK\_REACT\_CLASSES global](#removed-storybook_react_classes-global)
- [Removed STORYBOOK_REACT_CLASSES global](#removed-storybook_react_classes-global)
- [7.0 Deprecations and default changes](#70-deprecations-and-default-changes)
- [storyStoreV7 enabled by default](#storystorev7-enabled-by-default)
- [`Story` type deprecated](#story-type-deprecated)
Expand Down Expand Up @@ -302,6 +305,72 @@
- [Packages renaming](#packages-renaming)
- [Deprecated embedded addons](#deprecated-embedded-addons)

## From version 7.4.0 to 7.5.0

#### `storyStoreV6` and `storiesOf` is deprecated

`storyStoreV6` and `storiesOf` is deprecated and will be completely removed in Storybook 8.0.0.

If you're using `storiesOf` we recommend you migrate your stories to CSF3 for a better story writing experience.
In many cases you can get started with the migration by using two migration scripts:

```bash

# 1. convert storiesOf to CSF
npx storybook@latest migrate storiesof-to-csf --glob="**/*.stories.tsx" --parser=tsx

# 2. Convert CSF 2 to CSF 3
npx storybook@latest migrate csf-2-to-3 --glob="**/*.stories.tsx" --parser=tsx
```

They won't do a perfect migration so we recommend that you manually go through each file afterwards.

Alternatively you can build your own `storiesOf` implementation by leveraging the new (experimental) indexer API ([documentation](https://storybook.js.org/docs/react/api/main-config-indexers), [migration](#storyindexers-is-replaced-with-experimental_indexers)). A proof of concept of such an implementation can be seen in [this StackBlitz demo](https://stackblitz.com/edit/github-h2rgfk?file=README.md). See the demo's `README.md` for a deeper explanation of the implementation.

#### `storyIndexers` is replaced with `experimental_indexers`

Defining custom indexers for stories has become a more official - yet still experimental - API which is now configured at `experimental_indexers` instead of `storyIndexers` in `main.ts`. `storyIndexers` has been deprecated and will be fully removed in version 8.0.0.

The new experimental indexers are documented [here](https://storybook.js.org/docs/react/api/main-config-indexers). The most notable change from `storyIndexers` is that the indexer must now return a list of [`IndexInput`](https://github.com/storybookjs/storybook/blob/next/code/lib/types/src/modules/indexer.ts#L104-L148) instead of `CsfFile`. It's possible to construct an `IndexInput` from a `CsfFile` using the `CsfFile.indexInputs` getter.

That means you can convert an existing story indexer like this:

```diff
// .storybook/main.ts

import { readFileSync } from 'fs';
import { loadCsf } from '@storybook/csf-tools';

export default {
- storyIndexers = (indexers) => {
- const indexer = async (fileName, opts) => {
+ experimental_indexers = (indexers) => {
+ const createIndex = async (fileName, opts) => {
const code = readFileSync(fileName, { encoding: 'utf-8' });
const makeTitle = (userTitle) => {
// Do something with the auto title retrieved by Storybook
return userTitle;
};

// Parse the CSF file with makeTitle as a custom context
- return loadCsf(code, { ...compilationOptions, makeTitle, fileName }).parse();
+ return loadCsf(code, { ...compilationOptions, makeTitle, fileName }).parse().indexInputs;
};

return [
{
test: /(stories|story)\.[tj]sx?$/,
- indexer,
+ createIndex,
},
...(indexers || []),
];
},
};
```

As an addon author you can support previous versions of Storybook by setting both `storyIndexers` and `indexers_experimental`, without triggering the deprecation warning.

## From version 7.0.0 to 7.2.0

#### Addon API is more type-strict
Expand All @@ -311,14 +380,15 @@ When registering an addon using `@storybook/manager-api`, the addon API is now m
The `type` property is now a required field, and the `id` property should not be set anymore.

Here's a correct example:

```tsx
import { addons, types } from '@storybook/manager-api';

addons.register('my-addon', () => {
addons.add('my-addon/panel', {
type: types.PANEL,
title: 'My Addon',
render: ({ active }) => active ? <div>Hello World</div> : null,
render: ({ active }) => (active ? <div>Hello World</div> : null),
});
});
```
Expand Down Expand Up @@ -869,16 +939,16 @@ Given the following `main.js`:

```js
export default {
stories: ['../**/*.stories.*']
}
stories: ['../**/*.stories.*'],
};
```

If you want to restore the previous behavior to include `node_modules`, you can update it to:

```js
export default {
stories: ['../**/*.stories.*', '../**/node_modules/**/*.stories.*']
}
stories: ['../**/*.stories.*', '../**/node_modules/**/*.stories.*'],
};
```

The first glob would have node_modules automatically excluded by Storybook, and the second glob would include all stories that are under a nested `node_modules` directory.
Expand Down Expand Up @@ -1046,7 +1116,7 @@ Starting in 7.0, we drop support for Angular < 14

_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 <your-project>:storybook` to start Storybook.
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 <your-project>: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.

Expand Down
10 changes: 9 additions & 1 deletion code/lib/core-server/src/build-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import chalk from 'chalk';
import { copy, emptyDir, ensureDir } from 'fs-extra';
import { dirname, isAbsolute, join, resolve } from 'path';
import { global } from '@storybook/global';
import { logger } from '@storybook/node-logger';
import { deprecate, logger } from '@storybook/node-logger';
import { telemetry, getPrecedingUpgrade } from '@storybook/telemetry';
import type {
BuilderOptions,
Expand All @@ -23,6 +23,7 @@ import {
import { ConflictingStaticDirConfigError } from '@storybook/core-events/server-errors';

import isEqual from 'lodash/isEqual.js';
import dedent from 'ts-dedent';
import { outputStats } from './utils/output-stats';
import {
copyAllStaticFiles,
Expand Down Expand Up @@ -123,6 +124,13 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption
presets.apply<DocsOptions>('docs', {}),
]);

if (features?.storyStoreV7 === false) {
deprecate(
dedent`storyStoreV6 is deprecated, please migrate to storyStoreV7 instead.
- Refer to the migration guide at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#storystorev6-and-storiesof-is-deprecated`
);
}

const fullOptions: Options = {
...options,
presets,
Expand Down
10 changes: 9 additions & 1 deletion code/lib/core-server/src/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import invariant from 'tiny-invariant';
import type { CoreConfig, Options, StorybookConfig } from '@storybook/types';

import { logConfig } from '@storybook/core-common';
import { deprecate, logger } from '@storybook/node-logger';

import { logger } from '@storybook/node-logger';
import dedent from 'ts-dedent';
import { MissingBuilderError } from '@storybook/core-events/server-errors';
import { getMiddleware } from './utils/middleware';
import { getServerAddresses } from './utils/server-address';
Expand Down Expand Up @@ -37,6 +38,13 @@ export async function storybookDevServer(options: Options) {
getServerChannel(server)
);

if (features?.storyStoreV7 === false) {
deprecate(
dedent`storyStoreV6 is deprecated, please migrate to storyStoreV7 instead.
- Refer to the migration guide at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#storystorev6-and-storiesof-is-deprecated`
);
Comment on lines +42 to +45
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yannbf I'd like to hear your opinion on if we should continue to do deprecations warnings like this -in place-?

I'd love to figure out a way to use the errors-consolidation work you've done, to consolidate deprecation warnings like these.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's create a task for this!

}

let indexError: Error | undefined;
// try get index generator, if failed, send telemetry without storyCount, then rethrow the error
const initializedStoryIndexGenerator: Promise<StoryIndexGenerator | undefined> =
Expand Down
12 changes: 5 additions & 7 deletions code/lib/core-server/src/utils/StoryIndexGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type {
} from '@storybook/types';
import { userOrAutoTitleFromSpecifier, sortStoriesV7 } from '@storybook/preview-api';
import { commonGlobOptions, normalizeStoryPath } from '@storybook/core-common';
import { logger, once } from '@storybook/node-logger';
import { deprecate, logger, once } from '@storybook/node-logger';
import { getStorySortParameter } from '@storybook/csf-tools';
import { storyNameFromExport, toId } from '@storybook/csf';
import { analyze } from '@storybook/docs-mdx';
Expand Down Expand Up @@ -119,12 +119,6 @@ export class StoryIndexGenerator {
public readonly options: StoryIndexGeneratorOptions
) {
this.specifierToCache = new Map();
if (options.storyIndexers.length > 1) {
// TODO: write migration notes before enabling this warning
// deprecate(
// "'storyIndexers' is deprecated, please use 'indexers' instead. See migration notes at XXX"
// );
}
}

async initialize() {
Expand Down Expand Up @@ -298,6 +292,10 @@ export class StoryIndexGenerator {
invariant(indexer, `No matching indexer found for ${absolutePath}`);

if (indexer.indexer) {
deprecate(
dedent`'storyIndexers' is deprecated, please use 'experimental_indexers' instead. Found a deprecated indexer with matcher: ${indexer.test}
- Refer to the migration guide at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#storyindexers-is-replaced-with-experimental_indexers`
);
return this.extractStoriesFromDeprecatedIndexer({
indexer: indexer.indexer,
indexerOptions: { makeTitle: defaultMakeTitle },
Expand Down
2 changes: 1 addition & 1 deletion code/lib/types/src/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ export interface StorybookConfig {

/**
* Process CSF files for the story index.
* @soonDeprecated use {@link experimental_indexers} instead
* @deprecated use {@link experimental_indexers} instead
*/
storyIndexers?: PresetValue<StoryIndexer[]>;

Expand Down
4 changes: 2 additions & 2 deletions code/lib/types/src/modules/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export type Indexer = BaseIndexer & {
*/
createIndex: (fileName: string, options: IndexerOptions) => Promise<IndexInput[]>;
/**
* @soonDeprecated Use {@link index} instead
* @deprecated Use {@link index} instead
*/
indexer?: never;
};
Expand All @@ -79,7 +79,7 @@ export type DeprecatedIndexer = BaseIndexer & {
};

/**
* @soonDeprecated Use {@link Indexer} instead
* @deprecated Use {@link Indexer} instead
*/
export type StoryIndexer = Indexer | DeprecatedIndexer;

Expand Down