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

Vite: Fix framework option checks, and SSv6 #19062

Merged
merged 4 commits into from
Sep 1, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions code/lib/builder-vite/src/codegen-iframe-script.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
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';

export async function generateIframeScriptCode(options: ExtendedOptions) {
const { presets, frameworkPath, framework } = options;
const frameworkImportPath = frameworkPath || `@storybook/${framework}`;

const { presets } = options;
const frameworkName = await getFrameworkName(options);
const presetEntries = await presets.apply('config', [], options);
const previewEntries = await presets.apply('previewEntries', [], options);
const absolutePreviewEntries = previewEntries.map((entry) =>
Expand All @@ -28,7 +28,7 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
const code = `
// Ensure that the client API is initialized by the framework before any other iframe code
// is loaded. That way our client-apis can assume the existence of the API+store
import { configure } from '${frameworkImportPath}';
import { configure } from '${frameworkName}';

import * as clientApi from "@storybook/client-api";
import { logger } from '@storybook/client-logger';
Expand Down
11 changes: 6 additions & 5 deletions code/lib/builder-vite/src/codegen-modern-iframe-script.ts
Original file line number Diff line number Diff line change
@@ -1,11 +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 type { ExtendedOptions } from './types';

export async function generateModernIframeScriptCode(options: ExtendedOptions) {
const { presets, configDir, framework } = options;
const { presets, configDir } = options;
const frameworkName = await getFrameworkName(options);

const previewOrConfigFile = loadPreviewOrConfigFile({ configDir });
const presetEntries = await presets.apply('config', [], options);
Expand All @@ -17,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 === 'web-components') {
if (frameworkName === '@storybook/web-components-vite') {
return `
if (import.meta.hot) {
import.meta.hot.decline();
Expand Down Expand Up @@ -69,7 +70,7 @@ export async function generateModernIframeScriptCode(options: ExtendedOptions) {

preview.initialize({ importFn, getProjectAnnotations });

${generateHMRHandler(framework)};
${generateHMRHandler(frameworkName)};
`.trim();
return code;
}
7 changes: 4 additions & 3 deletions code/lib/builder-vite/src/transform-iframe-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import type { ExtendedOptions } from './types';
export type PreviewHtml = string | undefined;

export async function transformIframeHtml(html: string, options: ExtendedOptions) {
const { configType, features, framework, presets, serverChannelUrl, title } = options;
const { configType, features, presets, serverChannelUrl, title } = options;
const frameworkOptions = await presets.apply<Record<string, any> | null>('frameworkOptions');
const headHtmlSnippet = await presets.apply<PreviewHtml>('previewHead');
const bodyHtmlSnippet = await presets.apply<PreviewHtml>('previewBody');
const logLevel = await presets.apply('logLevel', undefined);
const frameworkOptions = await presets.apply(`${framework}Options`, {});

const coreOptions = await presets.apply<CoreConfig>('core');
const stories = normalizeStories(await options.presets.apply('stories', [], options), {
configDir: options.configDir,
Expand All @@ -23,7 +24,7 @@ export async function transformIframeHtml(html: string, options: ExtendedOptions
.replace('<!-- [TITLE HERE] -->', 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 : {})
Expand Down
3 changes: 0 additions & 3 deletions code/lib/builder-vite/src/types/extended-options.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import type { Options } from '@storybook/core-common';

// Using instead of `Record<string, string>` to provide better aware of used options
type IframeOptions = {
frameworkPath: string;
title: string;
// FIXME: Use @ndelangen's improved types
framework: string;
};

export type ExtendedOptions = Options & IframeOptions;
12 changes: 7 additions & 5 deletions code/lib/builder-vite/src/vite-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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';
Expand Down Expand Up @@ -40,7 +40,7 @@ export async function commonConfig(
}

export async function pluginConfig(options: ExtendedOptions, _type: PluginConfigType) {
const { framework } = options;
const frameworkName = await getFrameworkName(options);

const plugins = [
codeGeneratorPlugin(options),
Expand All @@ -52,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 === 'react' ? [] : [/\.([tj])sx?$/]
frameworkName === '@storybook/react-vite' ? [] : [/\.([tj])sx?$/]
),
}),
{
Expand All @@ -70,12 +70,14 @@ export async function pluginConfig(options: ExtendedOptions, _type: PluginConfig
},
] as Plugin[];

if (framework === 'preact') {
// TODO: framework doesn't exist, should move into framework when/if built
if (frameworkName === '@storybook/preact-vite') {
// eslint-disable-next-line global-require
plugins.push(require('@preact/preset-vite').default());
}

if (framework === 'glimmerx') {
// TODO: framework doesn't exist, should move into framework when/if built
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());
Expand Down
12 changes: 2 additions & 10 deletions code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import path from 'path';
import { dedent } from 'ts-dedent';
import { DefinePlugin, HotModuleReplacementPlugin, ProgressPlugin, ProvidePlugin } from 'webpack';
import type { Configuration } from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
Expand All @@ -18,6 +17,7 @@ import {
readTemplate,
loadPreviewOrConfigFile,
isPreservingSymlinks,
getFrameworkName,
} from '@storybook/core-common';
import { toRequireContextString, toImportFn } from '@storybook/core-webpack';
import type { BuilderOptions, TypescriptOptions } from '../types';
Expand Down Expand Up @@ -67,15 +67,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';
Expand Down
1 change: 1 addition & 0 deletions code/lib/core-common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
19 changes: 19 additions & 0 deletions code/lib/core-common/src/utils/get-framework-name.ts
Original file line number Diff line number Diff line change
@@ -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;
}