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 for GFM in MDX #21186

Merged
merged 8 commits into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions code/addons/gfm/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const path = require('path');
const baseConfig = require('../../jest.config.browser');

module.exports = {
...baseConfig,
displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep),
};
73 changes: 73 additions & 0 deletions code/addons/gfm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"name": "@storybook/addon-gfm",
ndelangen marked this conversation as resolved.
Show resolved Hide resolved
"version": "7.0.0-beta.52",
"description": "GitHub Formatted Markdown in storybook",
"keywords": [
"addon",
"github",
"markdown",
"formatting",
"tables",
"links"
],
"homepage": "https://github.com/storybookjs/storybook/tree/next/code/addons/gfm",
"bugs": {
"url": "https://github.com/storybookjs/storybook/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/storybookjs/storybook.git",
"directory": "addons/gfm"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/storybook"
},
"license": "MIT",
"exports": {
".": {
"node": "./dist/index.js",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./preset": {
"node": "./dist/index.js",
"require": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./package.json": "./package.json"
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist/**/*",
"README.md",
"*.js",
"*.d.ts"
],
"scripts": {
"check": "../../../scripts/node_modules/.bin/tsc --noEmit",
"prep": "../../../scripts/prepare/bundle.ts"
},
"dependencies": {
"@storybook/node-logger": "7.0.0-beta.52",
"remark-gfm": "^3.0.1",
"ts-dedent": "^2.0.0"
},
"devDependencies": {
"typescript": "~4.9.3"
},
"publishConfig": {
"access": "public"
},
"bundler": {
"entries": [
"./src/index.ts"
],
"formats": [
"cjs"
]
},
"gitHead": "1f559ed69a4fdd8eeb88e4190b16a8932104908e"
}
1 change: 1 addition & 0 deletions code/addons/gfm/preset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dist/index');
6 changes: 6 additions & 0 deletions code/addons/gfm/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@storybook/addon-gfm",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"implicitDependencies": [],
"type": "library"
}
19 changes: 19 additions & 0 deletions code/addons/gfm/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* eslint-disable no-param-reassign */
import { dedent } from 'ts-dedent';
import { deprecate } from '@storybook/node-logger';

import remarkGfm from 'remark-gfm';

export const mdxLoaderOptions = async (config: any) => {
config.mdxCompileOptions.remarkPlugins = config.mdxCompileOptions.remarkPlugins || [];
config.mdxCompileOptions.remarkPlugins.push(remarkGfm);
return config;
};

deprecate(dedent`
This addon is meant as a migration assistant for Storybook 7.0; and will likely be removed in a future version.
It's recommended you read this document:
https://storybook.js.org/docs/7.0/react/writing-docs/mdx#lack-of-github-flavored-markdown-gfm

Once you've made the necessary changes, you can remove this addon from your package.json and storybook config.
`);
7 changes: 7 additions & 0 deletions code/addons/gfm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"skipLibCheck": true
},
"include": ["src/**/*"]
}
4 changes: 3 additions & 1 deletion code/lib/cli/src/automigrate/fixes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { cra5 } from './cra5';
import { webpack5 } from './webpack5';
import { angular12 } from './angular12';
import { vue3 } from './vue3';
import { mdxgfm } from './mdx-gfm';
import { eslintPlugin } from './eslint-plugin';
import { builderVite } from './builder-vite';
import { sbScripts } from './sb-scripts';
import { sbBinary } from './sb-binary';
import { newFrameworks } from './new-frameworks/new-frameworks';
import { newFrameworks } from './new-frameworks';
import { removedGlobalClientAPIs } from './remove-global-client-apis';
import { mdx1to2 } from './mdx-1-to-2';
import { autodocsTrue } from './autodocs-true';
Expand All @@ -32,6 +33,7 @@ export const fixes: Fix[] = [
newFrameworks,
removedGlobalClientAPIs,
mdx1to2,
mdxgfm,
bareMdxStoriesGlob,
autodocsTrue,
addReact,
Expand Down
126 changes: 126 additions & 0 deletions code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import type { StorybookConfig } from '@storybook/types';
import type { PackageJson } from '../../js-package-manager';
import { makePackageManager, mockStorybookData } from '../helpers/testing-helpers';
import { mdxgfm } from './mdx-gfm';

const check = async ({
packageJson,
main: mainConfig,
storybookVersion = '7.0.0',
}: {
packageJson: PackageJson;
main: Partial<StorybookConfig> & Record<string, unknown>;
storybookVersion?: string;
}) => {
mockStorybookData({ mainConfig, storybookVersion });

return mdxgfm.check({
packageManager: makePackageManager(packageJson),
configDir: '',
});
};

describe('no-ops', () => {
const packageJson = {};
test('sb > 7.0', async () => {
await expect(
check({
packageJson,
main: {},
storybookVersion: '6.2.0',
})
).resolves.toBeFalsy();
});
test('legacyMdx1', async () => {
await expect(
check({
packageJson,
main: {
features: {
legacyMdx1: true,
},
},
})
).resolves.toBeFalsy();
});
test('with addon docs setup', async () => {
await expect(
check({
packageJson,
main: {
addons: [
{
name: '@storybook/addon-essentials',
options: {
docs: false,
},
},
{
name: '@storybook/addon-docs',
options: {
mdxPluginOptions: {
mdxCompileOptions: {
remarkPlugins: [() => {}],
},
},
},
},
],
},
})
).resolves.toBeFalsy();
});
test('with addon migration assistant addon added', async () => {
await expect(
check({
packageJson,
main: {
addons: ['@storybook/addon-gfm'],
},
})
).resolves.toBeFalsy();
});
});

describe('continue', () => {
const packageJson = {};
test('nothing configured at all', async () => {
await expect(
check({
packageJson,
main: {},
})
).resolves.toBeTruthy();
});
test('unconfigured addon-docs', async () => {
await expect(
check({
packageJson,
main: {
addons: [
{
name: '@storybook/addon-essentials',
options: {
docs: false,
},
},
{
name: '@storybook/addon-docs',
options: {},
},
],
},
})
).resolves.toBeTruthy();
});
test('unconfigured addon-essentials', async () => {
await expect(
check({
packageJson,
main: {
addons: ['@storybook/addon-essentials'],
},
})
).resolves.toBeTruthy();
});
});
81 changes: 81 additions & 0 deletions code/lib/cli/src/automigrate/fixes/mdx-gfm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import type { Preset } from '@storybook/types';
import { dedent } from 'ts-dedent';
import semver from 'semver';
import { getStorybookData, updateMainConfig } from '../helpers/mainConfigFile';
import type { Fix } from '../types';

const logger = console;

interface Options {
value?: boolean;
}

/**
*/
export const mdxgfm: Fix<Options> = {
id: 'gfm',

async check({ configDir, packageManager }) {
const { mainConfig, storybookVersion } = await getStorybookData({ packageManager, configDir });

if (!semver.gte(storybookVersion, '7.0.0')) {
return null;
}

const usesMDX1 = mainConfig?.features?.legacyMdx1 === true || false;
const skip =
usesMDX1 ||
!!mainConfig.addons?.find((item) => {
if (item === '@storybook/addon-gfm') {
return true;
}
if (typeof item === 'string') {
return false;
}
if (item.name === '@storybook/addon-docs') {
return item.options?.mdxPluginOptions?.mdxCompileOptions?.remarkPlugins?.length > 0;
}
return false;
});

if (skip) {
return null;
}

return {};
},

prompt() {
return dedent`
In MDX1 you had the option of using GitHub formatted markdown.

Storybook 7.0 uses MDX2 for compiling MDX, and thus no longer supports GFM out of the box.
Because of this you need to explicitly add the GFM plugin in the addon-docs options:
https://storybook.js.org/docs/7.0/react/writing-docs/mdx#lack-of-github-flavored-markdown-gfm

We recommend you follow the guide on the link above, however we can add a temporary storybook addon that helps make this migration easier.
We'll install the addon and add it to your storybook config.
`;
},

async run({ packageManager, dryRun, mainConfigPath, skipInstall }) {
if (!dryRun) {
if (!skipInstall) {
await packageManager.addDependencies({ installAsDevDependencies: true }, [
'@storybook/addon-gfm',
]);
}

await updateMainConfig({ mainConfigPath, dryRun }, async (main) => {
const addonsToAdd = ['@storybook/addon-gfm'];

const existingAddons = main.getFieldValue(['addons']) as Preset[];
const updatedAddons = [...existingAddons, ...addonsToAdd];
logger.info(`✅ Adding addon`);
if (!dryRun) {
main.setFieldValue(['addons'], updatedAddons);
}
});
}
},
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { StorybookConfig } from '@storybook/types';
import * as findUp from 'find-up';
import type { PackageJson } from '../../../js-package-manager';
import * as rendererHelpers from '../../helpers/detectRenderer';
import type { PackageJson } from '../../js-package-manager';
import * as rendererHelpers from '../helpers/detectRenderer';
import { newFrameworks } from './new-frameworks';
import { makePackageManager, mockStorybookData } from '../../helpers/testing-helpers';
import { makePackageManager, mockStorybookData } from '../helpers/testing-helpers';

jest.mock('find-up');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import semver from 'semver';
import { frameworkPackages, rendererPackages } from '@storybook/core-common';

import type { Preset } from '@storybook/types';
import type { Fix } from '../../types';
import type { PackageJsonWithDepsAndDevDeps } from '../../../js-package-manager';
import { getStorybookVersionSpecifier } from '../../../helpers';
import { detectRenderer } from '../../helpers/detectRenderer';
import { getNextjsAddonOptions, detectBuilderInfo, packagesMap } from './utils';
import { getStorybookData, updateMainConfig } from '../../helpers/mainConfigFile';
import type { Fix } from '../types';
import type { PackageJsonWithDepsAndDevDeps } from '../../js-package-manager';
import { getStorybookVersionSpecifier } from '../../helpers';
import { detectRenderer } from '../helpers/detectRenderer';
import {
getNextjsAddonOptions,
detectBuilderInfo,
packagesMap,
} from '../helpers/new-frameworks-utils';
import { getStorybookData, updateMainConfig } from '../helpers/mainConfigFile';

const logger = console;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as findUp from 'find-up';
import { detectBuilderInfo as _getBuilderInfo, getNextjsAddonOptions } from './utils';
import {
detectBuilderInfo as _getBuilderInfo,
getNextjsAddonOptions,
} from './new-frameworks-utils';

jest.mock('find-up');

Expand Down
Loading