Skip to content

Commit

Permalink
Merge pull request #17697 from storybookjs/1621-auto-disable-docgen
Browse files Browse the repository at this point in the history
Addon-docs: Auto-disable docs presets if docs/controls unused
  • Loading branch information
shilman authored Mar 14, 2022
2 parents 74caf0f + 2c351b3 commit edde091
Show file tree
Hide file tree
Showing 33 changed files with 256 additions and 130 deletions.
9 changes: 9 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<h1>Migration</h1>

- [From version 6.4.x to 6.5.0](#from-version-64x-to-650)
- [Docs framework refactor for React](#docs-framework-refactor-for-react)
- [Opt-in MDX2 support](#opt-in-mdx2-support)
- [CSF3 auto-title improvements](#csf3-auto-title-improvements)
- [Auto-title filename case](#auto-title-filename-case)
Expand Down Expand Up @@ -195,6 +196,14 @@

## From version 6.4.x to 6.5.0

### Docs framework refactor for React

SB6.5 moves framework specializations (e.g. ArgType inference, dynamic snippet rendering) out of `@storybook/addon-docs` and into the specific framework packages to which they apply (e.g. `@storybook/react`).

This change should not require any specific migrations on your part if you are using the docs addon as described in the documentation. However, if you are using `react-docgen` or `react-docgen-typescript` information in some custom way outside of `addon-docs`, you should be aware of this change.

In SB6.4, `@storybook/react` added `react-docgen` to its babel settings and `react-docgen-typescript` to its webpack settings. In SB6.5, this only happens if you are using `addon-docs` or `addon-controls`, either directly or indirectly through `addon-essentials`. If you're not using either of those addons, but require that information for some other addon, please configure that manually in your `.storybook/main.js` configuration. You can see the docs configuration here: https://github.com/storybookjs/storybook/blob/next/app/react/src/server/framework-preset-react-docs.ts

### Opt-in MDX2 support

SB6.5 adds experimental opt-in support for MDXv2. To install:
Expand Down
11 changes: 8 additions & 3 deletions addons/essentials/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { serverRequire } from '@storybook/core-common';

interface PresetOptions {
configDir?: string;
backgrounds?: any;
viewport?: any;
docs?: any;
docs?: boolean;
controls?: boolean;
actions?: boolean;
backgrounds?: boolean;
viewport?: boolean;
toolbars?: boolean;
measure?: boolean;
outline?: boolean;
}

const requireMain = (configDir: string) => {
Expand Down
3 changes: 2 additions & 1 deletion app/angular/src/server/framework-preset-angular-docs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import path from 'path';
import { StorybookConfig } from '@storybook/core-common';
import { hasDocsOrControls } from '@storybook/docs-tools';

export const config: StorybookConfig['config'] = (entry = [], options) => {
console.log({ options });
if (!hasDocsOrControls(options)) return entry;
return [...entry, path.join(__dirname, '../../../dist/ts3.9/client/docs/config')];
};
2 changes: 1 addition & 1 deletion app/ember/preset.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./dist/cjs/server/framework-preset-babel-ember');
module.exports = require('./dist/cjs/server/preset');
4 changes: 3 additions & 1 deletion app/ember/src/server/framework-preset-ember-docs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { StorybookConfig } from '@storybook/core-common';
import { findDistEsm } from '@storybook/core-common';
import { hasDocsOrControls } from '@storybook/docs-tools';

export const config: StorybookConfig['config'] = (entry = []) => {
export const config: StorybookConfig['config'] = (entry = [], options) => {
if (!hasDocsOrControls(options)) return entry;
return [...entry, findDistEsm(__dirname, 'client/docs/config')];
};
5 changes: 1 addition & 4 deletions app/ember/src/server/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@ import type { LoadOptions } from '@storybook/core-common';
export default {
packageJson: sync({ cwd: __dirname }).packageJson,
framework: 'ember',
frameworkPresets: [
require.resolve('./framework-preset-babel-ember.js'),
require.resolve('./framework-preset-ember-docs.js'),
],
frameworkPresets: [require.resolve('./preset')],
} as LoadOptions;
6 changes: 6 additions & 0 deletions app/ember/src/server/preset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { StorybookConfig } from '@storybook/core-common';

export const addons: StorybookConfig['addons'] = [
require.resolve('./framework-preset-babel-ember'),
require.resolve('./framework-preset-ember-docs'),
];
2 changes: 1 addition & 1 deletion app/html/preset.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./dist/cjs/server/framework-preset-html');
module.exports = require('./dist/cjs/server/preset');
7 changes: 5 additions & 2 deletions app/html/src/server/framework-preset-html-docs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { findDistEsm, StorybookConfig } from '@storybook/core-common';
import type { StorybookConfig } from '@storybook/core-common';
import { findDistEsm } from '@storybook/core-common';
import { hasDocsOrControls } from '@storybook/docs-tools';

export const config: StorybookConfig['config'] = (entry = []) => {
export const config: StorybookConfig['config'] = (entry = [], options) => {
if (!hasDocsOrControls(options)) return entry;
return [...entry, findDistEsm(__dirname, 'client/docs/config')];
};
5 changes: 1 addition & 4 deletions app/html/src/server/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,5 @@ import type { LoadOptions } from '@storybook/core-common';
export default {
packageJson: sync({ cwd: __dirname }).packageJson,
framework: 'html',
frameworkPresets: [
require.resolve('./framework-preset-html'),
require.resolve('./framework-preset-html-docs'),
],
frameworkPresets: [require.resolve('./preset')],
} as LoadOptions;
6 changes: 6 additions & 0 deletions app/html/src/server/preset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { StorybookConfig } from '@storybook/core-common';

export const addons: StorybookConfig['addons'] = [
require.resolve('./framework-preset-html'),
require.resolve('./framework-preset-html-docs'),
];
223 changes: 140 additions & 83 deletions app/react/src/server/framework-preset-react-docs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,105 +4,162 @@ import * as preset from './framework-preset-react-docs';

describe('framework-preset-react-docgen', () => {
const babelPluginReactDocgenPath = require.resolve('babel-plugin-react-docgen');
const presetsListWithDocs = [{ name: '@storybook/addon-docs', options: {}, preset: null }];

it('should return the babel config with the extra plugin', async () => {
const babelConfig = {
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
};
describe('react-docgen', () => {
it('should return the babel config with the extra plugin', async () => {
const babelConfig = {
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
};

const config = await preset.babel(babelConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: 'react-docgen',
} as TypescriptConfig),
},
} as any);
const config = await preset.babel(babelConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: 'react-docgen',
} as TypescriptConfig),
},
presetsList: presetsListWithDocs,
} as any);

expect(config).toEqual({
babelrc: false,
plugins: ['foo-plugin'],
presets: ['env', 'foo-preset'],
overrides: [
{
test: /\.(mjs|tsx?|jsx?)$/,
plugins: [
[
babelPluginReactDocgenPath,
{
DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES',
},
expect(config).toEqual({
babelrc: false,
plugins: ['foo-plugin'],
presets: ['env', 'foo-preset'],
overrides: [
{
test: /\.(mjs|tsx?|jsx?)$/,
plugins: [
[
babelPluginReactDocgenPath,
{
DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES',
},
],
],
],
},
],
},
],
});
});
});

it('should return the webpack config with the extra plugin', async () => {
const webpackConfig = {
plugins: [],
};
describe('react-docgen-typescript', () => {
it('should return the webpack config with the extra plugin', async () => {
const webpackConfig = {
plugins: [],
};

const config = await preset.webpackFinal(webpackConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: 'react-docgen-typescript',
} as TypescriptConfig),
},
});
const config = await preset.webpackFinal(webpackConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: 'react-docgen-typescript',
} as TypescriptConfig),
},
presetsList: presetsListWithDocs,
});

expect(config).toEqual({
plugins: [expect.any(ReactDocgenTypescriptPlugin)],
expect(config).toEqual({
plugins: [expect.any(ReactDocgenTypescriptPlugin)],
});
});
});

it('should not add any extra plugins', async () => {
const babelConfig = {
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
};
describe('no docgen', () => {
it('should not add any extra plugins', async () => {
const babelConfig = {
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
};

const webpackConfig = {
plugins: [],
};
const webpackConfig = {
plugins: [],
};

const outputBabelconfig = await preset.babel(babelConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: false,
} as TypescriptConfig),
},
});
const outputWebpackconfig = await preset.webpackFinal(webpackConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: false,
} as TypescriptConfig),
},
});
const outputBabelconfig = await preset.babel(babelConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: false,
} as TypescriptConfig),
},
presetsList: presetsListWithDocs,
});
const outputWebpackconfig = await preset.webpackFinal(webpackConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: false,
} as TypescriptConfig),
},
presetsList: presetsListWithDocs,
});

expect(outputBabelconfig).toEqual({
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
expect(outputBabelconfig).toEqual({
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
});
expect(outputWebpackconfig).toEqual({
plugins: [],
});
});
expect(outputWebpackconfig).toEqual({
plugins: [],
});

describe('no docs or controls addon used', () => {
it('should not add any extra plugins', async () => {
const babelConfig = {
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
};

const webpackConfig = {
plugins: [],
};

const outputBabelconfig = await preset.babel(babelConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: 'react-docgen-typescript',
} as TypescriptConfig),
},
presetsList: [],
});
const outputWebpackconfig = await preset.webpackFinal(webpackConfig, {
presets: {
// @ts-ignore
apply: async () =>
({
check: false,
reactDocgen: 'react-docgen-typescript',
} as TypescriptConfig),
},
presetsList: [],
});

expect(outputBabelconfig).toEqual({
babelrc: false,
presets: ['env', 'foo-preset'],
plugins: ['foo-plugin'],
});
expect(outputWebpackconfig).toEqual({
plugins: [],
});
});
});
});
14 changes: 10 additions & 4 deletions app/react/src/server/framework-preset-react-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { findDistEsm } from '@storybook/core-common';
import type { TransformOptions } from '@babel/core';
import type { Configuration } from 'webpack';
import ReactDocgenTypescriptPlugin from '@storybook/react-docgen-typescript-plugin';
import { hasDocsOrControls } from '@storybook/docs-tools';

export async function babel(config: TransformOptions, { presets }: Options) {
const typescriptOptions = await presets.apply<TypescriptConfig>('typescript', {} as any);
export async function babel(config: TransformOptions, options: Options) {
if (!hasDocsOrControls(options)) return config;

const typescriptOptions = await options.presets.apply<TypescriptConfig>('typescript', {} as any);

const { reactDocgen } = typescriptOptions;

Expand All @@ -31,8 +34,10 @@ export async function babel(config: TransformOptions, { presets }: Options) {
};
}

export async function webpackFinal(config: Configuration, { presets }: Options) {
const typescriptOptions = await presets.apply<TypescriptConfig>('typescript', {} as any);
export async function webpackFinal(config: Configuration, options: Options) {
if (!hasDocsOrControls(options)) return config;

const typescriptOptions = await options.presets.apply<TypescriptConfig>('typescript', {} as any);

const { reactDocgen, reactDocgenTypescriptOptions } = typescriptOptions;

Expand All @@ -54,5 +59,6 @@ export async function webpackFinal(config: Configuration, { presets }: Options)
}

export const config: StorybookConfig['config'] = (entry = [], options) => {
if (!hasDocsOrControls(options)) return entry;
return [...entry, findDistEsm(__dirname, 'client/docs/config')];
};
2 changes: 1 addition & 1 deletion app/svelte/preset.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./dist/cjs/server/framework-preset-svelte');
module.exports = require('./dist/cjs/server/preset');
Loading

0 comments on commit edde091

Please sign in to comment.