Skip to content

Commit

Permalink
Use an object instead of tuple for previewAnnotations
Browse files Browse the repository at this point in the history
  • Loading branch information
IanVS committed Nov 9, 2022
1 parent 18a6ba9 commit 9d9a92d
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 32 deletions.
16 changes: 8 additions & 8 deletions code/lib/builder-vite/src/codegen-iframe-script.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { getRendererName, getFrameworkName } from '@storybook/core-common';
import type { PreviewAnnotation } from '@storybook/types';
import { virtualPreviewFile, virtualStoriesFile } from './virtual-file-names';
import type { ExtendedOptions } from './types';
import { processPreviewAnnotation } from './utils/process-preview-annotation';
Expand All @@ -8,16 +9,15 @@ export async function generateIframeScriptCode(options: ExtendedOptions) {
const rendererName = await getRendererName(options);
const frameworkName = await getFrameworkName(options);

const previewAnnotations = await presets.apply('previewAnnotations', [], options);
const configEntries = [...previewAnnotations].filter(Boolean);
const previewAnnotations = await presets.apply<PreviewAnnotation[]>(
'previewAnnotations',
[],
options
);
const configEntries = [...previewAnnotations].filter(Boolean).map(processPreviewAnnotation);

const filesToImport = (files: string[], name: string) =>
files
.map(
(el, i) =>
`import ${name ? `* as ${name}_${i} from ` : ''}'${processPreviewAnnotation(el)}'`
)
.join('\n');
files.map((el, i) => `import ${name ? `* as ${name}_${i} from ` : ''}'${el}'`).join('\n');

const importArray = (name: string, length: number) =>
new Array(length).fill(0).map((_, i) => `${name}_${i}`);
Expand Down
3 changes: 2 additions & 1 deletion code/lib/builder-vite/src/codegen-modern-iframe-script.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { loadPreviewOrConfigFile, getFrameworkName } from '@storybook/core-common';
import type { PreviewAnnotation } from '@storybook/types';
import { virtualStoriesFile, virtualAddonSetupFile } from './virtual-file-names';
import type { ExtendedOptions } from './types';
import { processPreviewAnnotation } from './utils/process-preview-annotation';
Expand All @@ -8,7 +9,7 @@ export async function generateModernIframeScriptCode(options: ExtendedOptions) {
const frameworkName = await getFrameworkName(options);

const previewOrConfigFile = loadPreviewOrConfigFile({ configDir });
const previewAnnotations = await presets.apply<(string | string[])[]>(
const previewAnnotations = await presets.apply<PreviewAnnotation[]>(
'previewAnnotations',
[],
options
Expand Down
30 changes: 21 additions & 9 deletions code/lib/builder-vite/src/utils/process-preview-annotation.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
import type { PreviewAnnotation } from '@storybook/types';
import { resolve } from 'path';

/**
* Preview annotations can take several forms, and vite needs them to be a bit more restrained.
* For node_modules, we want bare imports (so vite can process them), and for files in the user's source,
* Preview annotations can take several forms, and vite needs them to be
* a bit more restrained.
*
* For node_modules, we want bare imports (so vite can process them),
* and for files in the user's source,
* we want absolute paths.
*/
export function processPreviewAnnotation(path: string | string[] | undefined) {
// If entry is a tuple, take the first, which is the non-absolute path.
// This is so that webpack can use an absolute path (the second item in the tuple), and
// continue supporting super-addons in pnp/pnpm without requiring them to re-export their
// sub-addons as we do in addon-essentials.
if (Array.isArray(path)) {
return path[0];
export function processPreviewAnnotation(path: PreviewAnnotation | undefined) {
// If entry is an object, take the first, which is the
// bare (non-absolute) specifier.
// This is so that webpack can use an absolute path, and
// continue supporting super-addons in pnp/pnpm without
// requiring them to re-export their sub-addons as we do
// in addon-essentials.
if (typeof path === 'object') {
return path.bare;
}
// resolve relative paths into absolute paths, but don't resolve "bare" imports
if (path?.startsWith('./') || path?.startsWith('../')) {
return resolve(path);
}
// This should not occur, since we use `.filter(Boolean)` prior to
// calling this function, but this makes typescript happy
if (!path) {
throw new Error('Could not determine path for previewAnnotation');
}

return path;
}
21 changes: 12 additions & 9 deletions code/lib/builder-webpack5/src/preview/iframe-webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TerserWebpackPlugin from 'terser-webpack-plugin';
import VirtualModulePlugin from 'webpack-virtual-modules';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';

import type { Options, CoreConfig, DocsOptions } from '@storybook/types';
import type { Options, CoreConfig, DocsOptions, PreviewAnnotation } from '@storybook/types';
import {
getRendererName,
stringifyProcessEnvs,
Expand Down Expand Up @@ -82,15 +82,18 @@ export default async (
const docsOptions = await presets.apply<DocsOptions>('docs');

const previewAnnotations = [
...(await presets.apply('previewAnnotations', [], options)).map((entry) => {
// If entry is a tuple, take the second, which is the absolute path.
// This is to maintain back-compat with community addons that bundle other addons.
// The vite builder uses the first element of the tuple, which is the bare import.
if (Array.isArray(entry)) {
return entry[1];
...(await presets.apply<PreviewAnnotation[]>('previewAnnotations', [], options)).map(
(entry) => {
// If entry is an object, use the absolute import specifier.
// This is to maintain back-compat with community addons that bundle other addons
// and package managers that "hide" sub dependencies (e.g. pnpm / yarn pnp)
// The vite builder uses the bare import specifier.
if (typeof entry === 'object') {
return entry.absolute;
}
return entry;
}
return entry;
}),
),
loadPreviewOrConfigFile(options),
].filter(Boolean);
const entries = (await presets.apply('entries', [], options)) as string[];
Expand Down
12 changes: 8 additions & 4 deletions code/lib/core-common/src/presets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,11 @@ export const resolveAddonName = (
return undefined;
};

// This is used to maintain back-compat with community addons that do not re-export their sub-addons but reference
// the sub-addon name directly. We need to turn it into an absolute path so that webpack can serve it up correctly
// when yarn pnp or pnpm is being used. Vite will be broken in such cases, because it does not process absolute paths,
// This is used to maintain back-compat with community addons that do not
// re-export their sub-addons but reference the sub-addon name directly.
// We need to turn it into an absolute path so that webpack can
// serve it up correctly when yarn pnp or pnpm is being used.
// Vite will be broken in such cases, because it does not process absolute paths,
// and it will try to import from the bare import, breaking in pnp/pnpm.
const absolutizeExport = (exportName: string) => {
return resolve(`${name}${exportName}`);
Expand Down Expand Up @@ -125,7 +127,9 @@ export const resolveAddonName = (
...(previewFile
? {
previewAnnotations: [
previewFileAbsolute ? [previewFile, previewFileAbsolute] : [previewFile],
previewFileAbsolute
? { bare: previewFile, absolute: previewFileAbsolute }
: previewFile,
],
}
: {}),
Expand Down
4 changes: 3 additions & 1 deletion code/lib/types/src/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,11 +462,13 @@ export interface CoreCommon_ResolvedAddonPreset {
name: string;
}

export type PreviewAnnotation = string | { bare: string; absolute: string };

export interface CoreCommon_ResolvedAddonVirtual {
type: 'virtual';
name: string;
managerEntries?: string[];
previewAnnotations?: (string | string[])[];
previewAnnotations?: PreviewAnnotation[];
presets?: (string | { name: string; options?: any })[];
}

Expand Down

0 comments on commit 9d9a92d

Please sign in to comment.