From 9d074e69c6aecc926d7390d4fdf657a0f9f23933 Mon Sep 17 00:00:00 2001 From: Josh Wooding <12938082+joshwooding@users.noreply.github.com> Date: Thu, 8 Dec 2022 01:46:21 +0000 Subject: [PATCH] Add csf-plugin to vite --- code/lib/builder-vite/package.json | 2 +- .../builder-vite/src/plugins/csf-plugin.ts | 15 +++ code/lib/builder-vite/src/plugins/index.ts | 2 +- .../src/plugins/source-loader-plugin.ts | 104 ------------------ code/lib/builder-vite/src/vite-config.ts | 3 +- code/ui/.storybook/main.ts | 2 - code/yarn.lock | 2 +- 7 files changed, 20 insertions(+), 110 deletions(-) create mode 100644 code/lib/builder-vite/src/plugins/csf-plugin.ts delete mode 100644 code/lib/builder-vite/src/plugins/source-loader-plugin.ts diff --git a/code/lib/builder-vite/package.json b/code/lib/builder-vite/package.json index 7b1701d9e4af..5c925aaef996 100644 --- a/code/lib/builder-vite/package.json +++ b/code/lib/builder-vite/package.json @@ -44,11 +44,11 @@ "@joshwooding/vite-plugin-react-docgen-typescript": "0.0.5", "@storybook/client-logger": "7.0.0-alpha.62", "@storybook/core-common": "7.0.0-alpha.62", + "@storybook/csf-plugin": "7.0.0-alpha.62", "@storybook/mdx2-csf": "next", "@storybook/node-logger": "7.0.0-alpha.62", "@storybook/preview": "7.0.0-alpha.62", "@storybook/preview-api": "7.0.0-alpha.62", - "@storybook/source-loader": "7.0.0-alpha.62", "@storybook/types": "7.0.0-alpha.62", "@vitejs/plugin-react": "^2.0.0", "browser-assert": "^1.2.1", diff --git a/code/lib/builder-vite/src/plugins/csf-plugin.ts b/code/lib/builder-vite/src/plugins/csf-plugin.ts new file mode 100644 index 000000000000..1e73af210713 --- /dev/null +++ b/code/lib/builder-vite/src/plugins/csf-plugin.ts @@ -0,0 +1,15 @@ +import type { Plugin } from 'vite'; +import { vite } from '@storybook/csf-plugin'; +import type { StorybookConfig } from '@storybook/types'; +import type { ExtendedOptions } from '../types'; + +export async function csfPlugin(config: ExtendedOptions): Promise { + const { presets } = config; + + const addons = await presets.apply('addons', []); + const docsOptions = + // @ts-expect-error - not sure what type to use here + addons.find((a) => [a, a.name].includes('@storybook/addon-docs'))?.options ?? {}; + + return vite(docsOptions?.csfPluginOptions); +} diff --git a/code/lib/builder-vite/src/plugins/index.ts b/code/lib/builder-vite/src/plugins/index.ts index 735c60aa86fa..114a09191365 100644 --- a/code/lib/builder-vite/src/plugins/index.ts +++ b/code/lib/builder-vite/src/plugins/index.ts @@ -2,4 +2,4 @@ export * from './inject-export-order-plugin'; export * from './mdx-plugin'; export * from './strip-story-hmr-boundaries'; export * from './code-generator-plugin'; -export * from './source-loader-plugin'; +export * from './csf-plugin'; diff --git a/code/lib/builder-vite/src/plugins/source-loader-plugin.ts b/code/lib/builder-vite/src/plugins/source-loader-plugin.ts deleted file mode 100644 index 97278620aeeb..000000000000 --- a/code/lib/builder-vite/src/plugins/source-loader-plugin.ts +++ /dev/null @@ -1,104 +0,0 @@ -import type { Plugin } from 'vite'; -import sourceLoaderTransform from '@storybook/source-loader'; -import MagicString from 'magic-string'; -import type { ExtendedOptions } from '../types'; - -const storyPattern = /\.stories\.[jt]sx?$/; -const storySourcePattern = /var __STORY__ = "(.*)"/; -const storySourceReplacement = '--STORY_SOURCE_REPLACEMENT--'; - -const mockClassLoader = (id: string) => ({ - // eslint-disable-next-line no-console - emitWarning: (message: string) => console.warn(message), - resourcePath: id, -}); - -// HACK: Until we can support only node 15+ and use string.prototype.replaceAll -const replaceAll = (str: string, search: string, replacement: string) => { - return str.split(search).join(replacement); -}; - -export function sourceLoaderPlugin(config: ExtendedOptions): Plugin | Plugin[] { - if (config.configType === 'DEVELOPMENT') { - return { - name: 'storybook:source-loader-plugin', - enforce: 'pre', - async transform(src: string, id: string) { - if (id.match(storyPattern)) { - const code: string = await sourceLoaderTransform.call(mockClassLoader(id), src); - const s = new MagicString(src); - // Entirely replace with new code - s.overwrite(0, src.length, code); - - return { - code: s.toString(), - map: s.generateMap({ hires: true, source: id }), - }; - } - return undefined; - }, - }; - } - - // In production, we need to be fancier, to avoid vite:define plugin from replacing values inside the `__STORY__` string - const storySources = new WeakMap>(); - - return [ - { - name: 'storybook-vite-source-loader-plugin', - enforce: 'pre', - buildStart() { - storySources.set(config, new Map()); - }, - async transform(src: string, id: string) { - if (id.match(storyPattern)) { - let code: string = await sourceLoaderTransform.call(mockClassLoader(id), src); - // eslint-disable-next-line @typescript-eslint/naming-convention - const [_, sourceString] = code.match(storySourcePattern) ?? [null, null]; - if (sourceString) { - const map = storySources.get(config); - map?.set(id, sourceString); - - // Remove story source so that it is not processed by vite:define plugin - code = replaceAll(code, sourceString, storySourceReplacement); - } - - const s = new MagicString(src); - // Entirely replace with new code - s.overwrite(0, src.length, code); - - return { - code: s.toString(), - map: s.generateMap(), - }; - } - return undefined; - }, - }, - { - name: 'storybook-vite-source-loader-plugin-post', - enforce: 'post', - buildStart() { - storySources.set(config, new Map()); - }, - async transform(src: string, id: string) { - if (id.match(storyPattern)) { - const s = new MagicString(src); - const map = storySources.get(config); - const storySourceStatement = map?.get(id); - // Put the previously-extracted source back in - if (storySourceStatement) { - const newCode = replaceAll(src, storySourceReplacement, storySourceStatement); - s.overwrite(0, src.length, newCode); - } - - return { - code: s.toString(), - map: s.generateMap(), - }; - } - return undefined; - }, - }, - ]; -} diff --git a/code/lib/builder-vite/src/vite-config.ts b/code/lib/builder-vite/src/vite-config.ts index 5917c6f0e3a0..9ed95d120b80 100644 --- a/code/lib/builder-vite/src/vite-config.ts +++ b/code/lib/builder-vite/src/vite-config.ts @@ -13,6 +13,7 @@ import { isPreservingSymlinks, getFrameworkName } from '@storybook/core-common'; import { globals } from '@storybook/preview/globals'; import { codeGeneratorPlugin, + csfPlugin, injectExportOrderPlugin, mdxPlugin, stripStoryHMRBoundary, @@ -74,7 +75,7 @@ export async function pluginConfig(options: ExtendedOptions) { const plugins = [ codeGeneratorPlugin(options), - // sourceLoaderPlugin(options), + await csfPlugin(options), mdxPlugin(options), injectExportOrderPlugin, stripStoryHMRBoundary(), diff --git a/code/ui/.storybook/main.ts b/code/ui/.storybook/main.ts index 155bc548ed21..3a5bfda16f38 100644 --- a/code/ui/.storybook/main.ts +++ b/code/ui/.storybook/main.ts @@ -1,4 +1,3 @@ -import { vite as csfPlugin } from '@storybook/csf-plugin'; import pluginTurbosnap from 'vite-plugin-turbosnap'; import type { StorybookConfig } from '../../frameworks/react-vite/dist'; @@ -65,7 +64,6 @@ const config: StorybookConfig = { ...viteConfig, plugins: [ ...(viteConfig.plugins || []), - csfPlugin({}), configType === 'PRODUCTION' ? pluginTurbosnap({ rootDir: viteConfig.root || '' }) : [], ], optimizeDeps: { ...viteConfig.optimizeDeps, force: true }, diff --git a/code/yarn.lock b/code/yarn.lock index 37fb19ab60d5..a685a85ca25c 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -5873,11 +5873,11 @@ __metadata: "@joshwooding/vite-plugin-react-docgen-typescript": 0.0.5 "@storybook/client-logger": 7.0.0-alpha.62 "@storybook/core-common": 7.0.0-alpha.62 + "@storybook/csf-plugin": 7.0.0-alpha.62 "@storybook/mdx2-csf": next "@storybook/node-logger": 7.0.0-alpha.62 "@storybook/preview": 7.0.0-alpha.62 "@storybook/preview-api": 7.0.0-alpha.62 - "@storybook/source-loader": 7.0.0-alpha.62 "@storybook/types": 7.0.0-alpha.62 "@types/express": ^4.17.13 "@types/node": ^16.0.0