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

CLI: Add automigration to @storybook/builder-vite #17829

Merged
merged 2 commits into from Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions MIGRATION.md
@@ -1,6 +1,7 @@
<h1>Migration</h1>

- [From version 6.4.x to 6.5.0](#from-version-64x-to-650)
- [Vite builder renamed](#vite-builder-renamed)
- [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)
Expand Down Expand Up @@ -196,6 +197,16 @@

## From version 6.4.x to 6.5.0

### Vite builder renamed

SB6.5 renames Storybook's [Vite builder](https://github.com/storybookjs/builder-vite) from `storybook-builder-vite` to `@storybook/builder-vite`. This move is part of a larger effort to improve Vite support in Storybook.

Storybook's `automigrate` command can migrate for you. To manually migrate:

1. Remove `storybook-builder-vite` from your `package.json` dependencies
2. Install `@storybook/builder-vite`
3. Update your `core.builder` setting in `.storybook/main.js` to `@storybook/builder-vite`.

### 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`).
Expand Down
52 changes: 52 additions & 0 deletions lib/cli/src/automigrate/fixes/builder-vite.test.ts
@@ -0,0 +1,52 @@
/* eslint-disable no-underscore-dangle */
import path from 'path';
import { JsPackageManager } from '../../js-package-manager';
import { builderVite } from './builder-vite';

// eslint-disable-next-line global-require, jest/no-mocks-import
jest.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra'));

const checkBuilderVite = async ({ packageJson = {}, main }) => {
// eslint-disable-next-line global-require
require('fs-extra').__setMockFiles({
[path.join('.storybook', 'main.js')]: `module.exports = ${JSON.stringify(main)};`,
});
const packageManager = {
retrievePackageJson: () => ({ dependencies: {}, devDependencies: {}, ...packageJson }),
} as JsPackageManager;
return builderVite.check({ packageManager });
};

describe('builder-vite fix', () => {
describe('storybook-builder-vite', () => {
it('using storybook-builder-vite', async () => {
const main = { core: { builder: 'storybook-builder-vite' } };
await expect(checkBuilderVite({ main })).resolves.toMatchObject({
builder: 'storybook-builder-vite',
});
});
it('using storybook-builder-vite with options', async () => {
const main = { core: { builder: { name: 'storybook-builder-vite', options: {} } } };
await expect(checkBuilderVite({ main })).resolves.toMatchObject({
builder: {
name: 'storybook-builder-vite',
options: {},
},
});
});
});
describe('other builders', () => {
it('using @storybook/builder-vite', async () => {
const main = { core: { builder: { name: '@storybook/builder-vite', options: {} } } };
await expect(checkBuilderVite({ main })).resolves.toBeFalsy();
});
it('using webpack5', async () => {
const main = { core: { builder: 'webpack5' } };
await expect(checkBuilderVite({ main })).resolves.toBeFalsy();
});
it('no builder specified', async () => {
const main = {};
await expect(checkBuilderVite({ main })).resolves.toBeFalsy();
});
});
});
94 changes: 94 additions & 0 deletions lib/cli/src/automigrate/fixes/builder-vite.ts
@@ -0,0 +1,94 @@
import chalk from 'chalk';
import dedent from 'ts-dedent';

import { ConfigFile, readConfig, writeConfig } from '@storybook/csf-tools';

import { Fix } from '../types';
import { getStorybookInfo } from '../helpers/getStorybookInfo';
import { PackageJson, writePackageJson } from '../../js-package-manager';

const logger = console;

interface BuilderViteOptions {
builder: any;
main: ConfigFile;
packageJson: PackageJson;
}

/**
* Is the user using 'storybook-builder-vite' in their project?
*
* If so, prompt them to upgrade to '@storybook/builder-vite'.
*
* - Add '@storybook/builder-vite' as dev dependency
* - Remove 'storybook-builder-vite' dependency
* - Add core.builder = '@storybook/builder-vite' to main.js
*/
export const builderVite: Fix<BuilderViteOptions> = {
id: 'builder-vite',

async check({ packageManager }) {
const packageJson = packageManager.retrievePackageJson();
const { mainConfig } = getStorybookInfo(packageJson);
if (!mainConfig) {
logger.warn('Unable to find storybook main.js config');
return null;
}
const main = await readConfig(mainConfig);
const builder = main.getFieldValue(['core', 'builder']);
const builderName = typeof builder === 'string' ? builder : builder?.name;

if (builderName !== 'storybook-builder-vite') {
logger.info(`Not using community vite builder, skipping`);
return null;
}

return { builder, main, packageJson };
},

prompt({ builder }) {
const builderFormatted = chalk.cyan(JSON.stringify(builder, null, 2));

return dedent`
We've detected you're using the community vite builder: ${builderFormatted}

'storybook-builder-vite' is deprecated and now located at ${chalk.cyan(
'@storybook/builder-vite'
)}.

We can upgrade your project to use the new builder automatically.

More info: ${chalk.yellow(
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#vite-builder-renamed'
)}
`;
},

async run({ result: { builder, main, packageJson }, packageManager, dryRun }) {
const { dependencies = {}, devDependencies = {} } = packageJson;

logger.info(`Removing existing 'storybook-builder-vite' dependency`);
if (!dryRun) {
delete dependencies['storybook-builder-vite'];
delete devDependencies['storybook-builder-vite'];
writePackageJson(packageJson);
}

logger.info(`Adding '@storybook/builder-vite' as dev dependency`);
if (!dryRun) {
packageManager.addDependencies({ installAsDevDependencies: true }, [
'@storybook/builder-vite',
]);
}

logger.info(`Updating main.js to use vite builder`);
if (!dryRun) {
const updatedBuilder =
typeof builder === 'string'
? '@storybook/builder-vite'
: { name: '@storybook/builder-vite', options: builder.options };
main.setFieldValue(['core', 'builder'], updatedBuilder);
await writeConfig(main);
}
},
};
3 changes: 2 additions & 1 deletion lib/cli/src/automigrate/fixes/index.ts
Expand Up @@ -3,7 +3,8 @@ import { webpack5 } from './webpack5';
import { angular12 } from './angular12';
import { mainjsFramework } from './mainjsFramework';
import { eslintPlugin } from './eslint-plugin';
import { builderVite } from './builder-vite';
import { Fix } from '../types';

export * from '../types';
export const fixes: Fix[] = [cra5, webpack5, angular12, mainjsFramework, eslintPlugin];
export const fixes: Fix[] = [cra5, webpack5, angular12, mainjsFramework, eslintPlugin, builderVite];