From 0aca22eb321f7ff6bc97a3df3641f30e3cfb5c7d Mon Sep 17 00:00:00 2001 From: Ian VanSchooten Date: Wed, 31 Aug 2022 08:24:24 -0400 Subject: [PATCH] Extract getFrameworkName to core-common --- .../builder-vite/src/codegen-iframe-script.ts | 2 +- .../src/codegen-modern-iframe-script.ts | 11 +++++------ .../builder-vite/src/transform-iframe-html.ts | 13 ++----------- .../src/utils/get-framework-name.ts | 6 ------ code/lib/builder-vite/src/vite-config.ts | 11 +++++------ .../src/preview/iframe-webpack.config.ts | 11 ++--------- code/lib/core-common/src/index.ts | 1 + .../src/utils/get-framework-name.ts | 19 +++++++++++++++++++ 8 files changed, 35 insertions(+), 39 deletions(-) delete mode 100644 code/lib/builder-vite/src/utils/get-framework-name.ts create mode 100644 code/lib/core-common/src/utils/get-framework-name.ts diff --git a/code/lib/builder-vite/src/codegen-iframe-script.ts b/code/lib/builder-vite/src/codegen-iframe-script.ts index e282ae287c2f..4a473faa437b 100644 --- a/code/lib/builder-vite/src/codegen-iframe-script.ts +++ b/code/lib/builder-vite/src/codegen-iframe-script.ts @@ -1,8 +1,8 @@ import { isAbsolute, resolve } from 'path'; +import { getFrameworkName } from '@storybook/core-common'; import { virtualPreviewFile, virtualStoriesFile } from './virtual-file-names'; import { transformAbsPath } from './utils/transform-abs-path'; import type { ExtendedOptions } from './types'; -import { getFrameworkName } from './utils/get-framework-name'; export async function generateIframeScriptCode(options: ExtendedOptions) { const { presets } = options; diff --git a/code/lib/builder-vite/src/codegen-modern-iframe-script.ts b/code/lib/builder-vite/src/codegen-modern-iframe-script.ts index 35002961986b..94aa05ad6092 100644 --- a/code/lib/builder-vite/src/codegen-modern-iframe-script.ts +++ b/code/lib/builder-vite/src/codegen-modern-iframe-script.ts @@ -1,13 +1,12 @@ import { isAbsolute, resolve } from 'path'; -import { loadPreviewOrConfigFile } from '@storybook/core-common'; +import { loadPreviewOrConfigFile, getFrameworkName } from '@storybook/core-common'; import { virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names'; import { transformAbsPath } from './utils/transform-abs-path'; -import { getFrameworkName } from './utils/get-framework-name'; import type { ExtendedOptions } from './types'; export async function generateModernIframeScriptCode(options: ExtendedOptions) { const { presets, configDir } = options; - const framework = await getFrameworkName(options); + const frameworkName = await getFrameworkName(options); const previewOrConfigFile = loadPreviewOrConfigFile({ configDir }); const presetEntries = await presets.apply('config', [], options); @@ -19,9 +18,9 @@ export async function generateModernIframeScriptCode(options: ExtendedOptions) { .filter(Boolean) .map((configEntry) => transformAbsPath(configEntry as string)); - const generateHMRHandler = (framework: string): string => { + const generateHMRHandler = (frameworkName: string): string => { // Web components are not compatible with HMR, so disable HMR, reload page instead. - if (framework === '@storybook/web-components-vite') { + if (frameworkName === '@storybook/web-components-vite') { return ` if (import.meta.hot) { import.meta.hot.decline(); @@ -71,7 +70,7 @@ export async function generateModernIframeScriptCode(options: ExtendedOptions) { preview.initialize({ importFn, getProjectAnnotations }); - ${generateHMRHandler(framework)}; + ${generateHMRHandler(frameworkName)}; `.trim(); return code; } diff --git a/code/lib/builder-vite/src/transform-iframe-html.ts b/code/lib/builder-vite/src/transform-iframe-html.ts index c8e880d43092..9e058f4cc0fd 100644 --- a/code/lib/builder-vite/src/transform-iframe-html.ts +++ b/code/lib/builder-vite/src/transform-iframe-html.ts @@ -1,25 +1,16 @@ import { normalizeStories } from '@storybook/core-common'; import type { CoreConfig } from '@storybook/core-common'; -import { getFrameworkName } from './utils/get-framework-name'; import type { ExtendedOptions } from './types'; export type PreviewHtml = string | undefined; export async function transformIframeHtml(html: string, options: ExtendedOptions) { const { configType, features, presets, serverChannelUrl, title } = options; - const framework = await getFrameworkName(options); + const frameworkOptions = await presets.apply | null>('frameworkOptions'); const headHtmlSnippet = await presets.apply('previewHead'); const bodyHtmlSnippet = await presets.apply('previewBody'); const logLevel = await presets.apply('logLevel', undefined); - // TODO: pull this into frameworks? - let frameworkOptions; - if (framework.includes('react')) { - frameworkOptions = await presets.apply(`reactOptions`, {}); - } else if (framework.includes('svelte')) { - frameworkOptions = await presets.apply(`svelteOptions`, {}); - } - const coreOptions = await presets.apply('core'); const stories = normalizeStories(await options.presets.apply('stories', [], options), { configDir: options.configDir, @@ -33,7 +24,7 @@ export async function transformIframeHtml(html: string, options: ExtendedOptions .replace('', title || 'Storybook') .replace('[CONFIG_TYPE HERE]', configType || '') .replace('[LOGLEVEL HERE]', logLevel || '') - .replace(`'[FRAMEWORK_OPTIONS HERE]'`, JSON.stringify(frameworkOptions || {})) + .replace(`'[FRAMEWORK_OPTIONS HERE]'`, JSON.stringify(frameworkOptions)) .replace( `'[CHANNEL_OPTIONS HERE]'`, JSON.stringify(coreOptions && coreOptions.channelOptions ? coreOptions.channelOptions : {}) diff --git a/code/lib/builder-vite/src/utils/get-framework-name.ts b/code/lib/builder-vite/src/utils/get-framework-name.ts deleted file mode 100644 index 0db7009c0f05..000000000000 --- a/code/lib/builder-vite/src/utils/get-framework-name.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { ExtendedOptions } from '../types'; - -export async function getFrameworkName(options: ExtendedOptions) { - const framework = await options.presets.apply('framework', '', options); - return typeof framework === 'object' ? framework.name : framework; -} diff --git a/code/lib/builder-vite/src/vite-config.ts b/code/lib/builder-vite/src/vite-config.ts index da0ac5048eb5..66b5fc50343a 100644 --- a/code/lib/builder-vite/src/vite-config.ts +++ b/code/lib/builder-vite/src/vite-config.ts @@ -3,13 +3,12 @@ import fs from 'fs'; import { Plugin } from 'vite'; import viteReact from '@vitejs/plugin-react'; import type { UserConfig } from 'vite'; -import { isPreservingSymlinks } from '@storybook/core-common'; +import { isPreservingSymlinks, getFrameworkName } from '@storybook/core-common'; import { allowedEnvPrefix as envPrefix } from './envs'; import { codeGeneratorPlugin } from './code-generator-plugin'; import { injectExportOrderPlugin } from './inject-export-order-plugin'; import { mdxPlugin } from './plugins/mdx-plugin'; import { noFouc } from './plugins/no-fouc'; -import { getFrameworkName } from './utils/get-framework-name'; import type { ExtendedOptions } from './types'; export type PluginConfigType = 'build' | 'development'; @@ -41,7 +40,7 @@ export async function commonConfig( } export async function pluginConfig(options: ExtendedOptions, _type: PluginConfigType) { - const framework = await getFrameworkName(options); + const frameworkName = await getFrameworkName(options); const plugins = [ codeGeneratorPlugin(options), @@ -53,7 +52,7 @@ export async function pluginConfig(options: ExtendedOptions, _type: PluginConfig viteReact({ // Do not treat story files as HMR boundaries, storybook itself needs to handle them. exclude: [/\.stories\.([tj])sx?$/, /node_modules/].concat( - framework === '@storybook/react-vite' ? [] : [/\.([tj])sx?$/] + frameworkName === '@storybook/react-vite' ? [] : [/\.([tj])sx?$/] ), }), { @@ -72,13 +71,13 @@ export async function pluginConfig(options: ExtendedOptions, _type: PluginConfig ] as Plugin[]; // TODO: framework doesn't exist, should move into framework when/if built - if (framework === '@storybook/preact-vite') { + if (frameworkName === '@storybook/preact-vite') { // eslint-disable-next-line global-require plugins.push(require('@preact/preset-vite').default()); } // TODO: framework doesn't exist, should move into framework when/if built - if (framework === '@storybook/glimmerx-vite') { + if (frameworkName === '@storybook/glimmerx-vite') { // eslint-disable-next-line global-require, import/extensions const plugin = require('vite-plugin-glimmerx/index.cjs'); plugins.push(plugin.default()); diff --git a/code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts b/code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts index 6b6216298369..412d55afd68b 100644 --- a/code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts +++ b/code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts @@ -18,6 +18,7 @@ import { readTemplate, loadPreviewOrConfigFile, isPreservingSymlinks, + getFrameworkName, } from '@storybook/core-common'; import { toRequireContextString, toImportFn } from '@storybook/core-webpack'; import type { BuilderOptions, TypescriptOptions } from '../types'; @@ -67,15 +68,7 @@ export default async ( serverChannelUrl, } = options; - const framework = await presets.apply('framework', undefined); - if (!framework) { - throw new Error(dedent` - You must to specify a framework in '.storybook/main.js' config. - - https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-field-mandatory - `); - } - const frameworkName = typeof framework === 'string' ? framework : framework.name; + const frameworkName = await getFrameworkName(options); const frameworkOptions = await presets.apply('frameworkOptions'); const isProd = configType === 'PRODUCTION'; diff --git a/code/lib/core-common/src/index.ts b/code/lib/core-common/src/index.ts index 2fb7ff64b64c..5b95a7716571 100644 --- a/code/lib/core-common/src/index.ts +++ b/code/lib/core-common/src/index.ts @@ -9,6 +9,7 @@ export * from './utils/interpret-files'; export * from './utils/interpret-require'; export * from './utils/load-custom-presets'; export * from './utils/load-main-config'; +export * from './utils/get-framework-name'; export * from './utils/get-storybook-configuration'; export * from './utils/get-storybook-info'; export * from './utils/get-storybook-refs'; diff --git a/code/lib/core-common/src/utils/get-framework-name.ts b/code/lib/core-common/src/utils/get-framework-name.ts new file mode 100644 index 000000000000..1e93ea811823 --- /dev/null +++ b/code/lib/core-common/src/utils/get-framework-name.ts @@ -0,0 +1,19 @@ +import { dedent } from 'ts-dedent'; +import type { Options } from '../types'; + +/** + * Framework can be a string or an object. This utility always returns the string name. + */ +export async function getFrameworkName(options: Options) { + const framework = await options.presets.apply('framework', '', options); + + if (!framework) { + throw new Error(dedent` + You must specify a framework in '.storybook/main.js' config. + + https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#framework-field-mandatory + `); + } + + return typeof framework === 'object' ? framework.name : framework; +}