mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-08 05:51:48 +08:00
add missing-babelrc automigration
This commit is contained in:
parent
5f23fc59c6
commit
834c796011
@ -17,6 +17,7 @@ import { autodocsTrue } from './autodocs-true';
|
||||
import { sveltekitFramework } from './sveltekit-framework';
|
||||
import { addReact } from './add-react';
|
||||
import { nodeJsRequirement } from './nodejs-requirement';
|
||||
import { missingBabelRc } from './missing-babelrc';
|
||||
|
||||
export * from '../types';
|
||||
|
||||
@ -38,4 +39,5 @@ export const fixes: Fix[] = [
|
||||
mdx1to2,
|
||||
autodocsTrue,
|
||||
addReact,
|
||||
missingBabelRc,
|
||||
];
|
||||
|
91
code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts
Normal file
91
code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts
Normal file
@ -0,0 +1,91 @@
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
/// <reference types="@types/jest" />;
|
||||
|
||||
import path from 'path';
|
||||
import type { JsPackageManager } from '../../js-package-manager';
|
||||
import { missingBabelRc } from './missing-babelrc';
|
||||
|
||||
// eslint-disable-next-line global-require, jest/no-mocks-import
|
||||
jest.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra'));
|
||||
|
||||
const babelContent = JSON.stringify({
|
||||
sourceType: 'unambiguous',
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
chrome: 100,
|
||||
},
|
||||
},
|
||||
],
|
||||
'@babel/preset-typescript',
|
||||
'@babel/preset-react',
|
||||
],
|
||||
plugins: [],
|
||||
});
|
||||
|
||||
const check = async ({ packageJson = {}, main = {}, extraFiles }: any) => {
|
||||
if (extraFiles) {
|
||||
// eslint-disable-next-line global-require
|
||||
require('fs-extra').__setMockFiles({
|
||||
[path.join('.storybook', 'main.js')]: `module.exports = ${JSON.stringify(main)};`,
|
||||
...extraFiles,
|
||||
});
|
||||
}
|
||||
const packageManager = {
|
||||
retrievePackageJson: () => ({ dependencies: {}, devDependencies: {}, ...packageJson }),
|
||||
} as JsPackageManager;
|
||||
return missingBabelRc.check({ packageManager });
|
||||
};
|
||||
|
||||
describe('missing-babelrc fix', () => {
|
||||
it('skips when babelrc config is present', async () => {
|
||||
const packageJson = {
|
||||
devDependencies: {
|
||||
'@storybook/react': '^7.0.0',
|
||||
'@storybook/react-webpack5': '^7.0.0',
|
||||
},
|
||||
};
|
||||
|
||||
// different babel extensions
|
||||
await expect(
|
||||
check({ extraFiles: { '.babelrc': babelContent }, packageJson })
|
||||
).resolves.toBeNull();
|
||||
await expect(
|
||||
check({ extraFiles: { '.babelrc.json': babelContent }, packageJson })
|
||||
).resolves.toBeNull();
|
||||
await expect(
|
||||
check({ extraFiles: { 'babel.config.json': babelContent }, packageJson })
|
||||
).resolves.toBeNull();
|
||||
|
||||
// babel field in package.json
|
||||
await expect(
|
||||
check({ packageJson: { ...packageJson, babel: babelContent } })
|
||||
).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it('skips when using a framework that provides babel config', async () => {
|
||||
const packageJson = {
|
||||
devDependencies: {
|
||||
'@storybook/react': '^7.0.0',
|
||||
'@storybook/nextjs': '^7.0.0',
|
||||
},
|
||||
};
|
||||
|
||||
await expect(check({ packageJson })).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it('prompts when babelrc file is missing and framework does not provide babel config', async () => {
|
||||
const packageJson = {
|
||||
devDependencies: {
|
||||
'@storybook/react': '^7.0.0',
|
||||
'@storybook/react-webpack5': '^7.0.0',
|
||||
},
|
||||
};
|
||||
|
||||
await expect(check({ packageJson })).resolves.toBe({
|
||||
needsBabelRc: true,
|
||||
});
|
||||
});
|
||||
});
|
91
code/lib/cli/src/automigrate/fixes/missing-babelrc.ts
Normal file
91
code/lib/cli/src/automigrate/fixes/missing-babelrc.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import chalk from 'chalk';
|
||||
import dedent from 'ts-dedent';
|
||||
import semver from 'semver';
|
||||
import { getStorybookInfo } from '@storybook/core-common';
|
||||
import { loadPartialConfigAsync } from '@babel/core';
|
||||
import { readConfig } from '@storybook/csf-tools';
|
||||
import type { Fix } from '../types';
|
||||
|
||||
interface MissingBabelRcOptions {
|
||||
needsBabelRc: boolean;
|
||||
}
|
||||
|
||||
const logger = console;
|
||||
|
||||
const frameworksThatNeedBabelConfig = [
|
||||
'@storybook/angular',
|
||||
'@storybook/react-webpack5',
|
||||
'@storybook/vue-webpack5',
|
||||
'@storybook/vue3-webpack5',
|
||||
'@storybook/preact-webpack5',
|
||||
'@storybook/html-webpack5',
|
||||
'@storybook/react-vite',
|
||||
'@storybook/vue-vite',
|
||||
'@storybook/vue3-vite',
|
||||
'@storybook/preact-vite',
|
||||
'@storybook/html-vite',
|
||||
];
|
||||
|
||||
export const missingBabelRc: Fix<MissingBabelRcOptions> = {
|
||||
id: 'missing-babelrc',
|
||||
promptOnly: true,
|
||||
|
||||
async check({ packageManager }) {
|
||||
const packageJson = packageManager.retrievePackageJson();
|
||||
const { mainConfig, version: storybookVersion } = getStorybookInfo(packageJson);
|
||||
|
||||
const storybookCoerced = storybookVersion && semver.coerce(storybookVersion)?.version;
|
||||
if (!storybookCoerced) {
|
||||
throw new Error(dedent`
|
||||
❌ Unable to determine storybook version.
|
||||
🤔 Are you running automigrate from your project directory?
|
||||
`);
|
||||
}
|
||||
|
||||
if (!semver.gte(storybookCoerced, '7.0.0')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!mainConfig) {
|
||||
logger.warn('Unable to find storybook main.js config, skipping');
|
||||
return null;
|
||||
}
|
||||
|
||||
const main = await readConfig(mainConfig);
|
||||
|
||||
const frameworkField = main.getFieldValue(['framework']);
|
||||
const frameworkPackage =
|
||||
typeof frameworkField === 'string' ? frameworkField : frameworkField?.name;
|
||||
|
||||
if (frameworksThatNeedBabelConfig.includes(frameworkPackage)) {
|
||||
const config = await loadPartialConfigAsync();
|
||||
if (!config.config && !packageJson.babel) {
|
||||
return { needsBabelRc: true };
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
prompt() {
|
||||
return dedent`
|
||||
${chalk.bold(
|
||||
chalk.red('Attention')
|
||||
)}: We could not automatically make this change. You'll need to do it manually.
|
||||
|
||||
Storybook now uses Babel mode v7 exclusively. In 6.x, Storybook provided its own babel settings out of the box. Now, Storybook's uses your project's babel settings (.babelrc, babel.config.js, etc.) instead.
|
||||
|
||||
In the new mode, Storybook expects you to provide a configuration file. If you want a configuration file that's equivalent to the 6.x default, you can run the following command in your project directory:
|
||||
|
||||
${chalk.blue('npx sb@next babelrc')}
|
||||
|
||||
This will create a ${chalk.blue(
|
||||
'.babelrc.json'
|
||||
)} file with some basic configuration and add new package devDependencies accordingly.
|
||||
|
||||
Please see the migration guide for more information:
|
||||
${chalk.yellow(
|
||||
'https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#babel-mode-v7-exclusively'
|
||||
)}
|
||||
`;
|
||||
},
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user