Skip to content
Draft
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
53 changes: 28 additions & 25 deletions code/addons/docs/src/mdx-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,34 @@ export async function mdxPlugin(options: Options): Promise<Plugin> {
return {
name: 'storybook:mdx-plugin',
enforce: 'pre',
async transform(src, id) {
if (!filter(id)) {
return undefined;
}

const mdxLoaderOptions: CompileOptions = await presets.apply('mdxLoaderOptions', {
...mdxPluginOptions,
mdxCompileOptions: {
providerImportSource: import.meta.resolve('@storybook/addon-docs/mdx-react-shim'),
...mdxPluginOptions?.mdxCompileOptions,
rehypePlugins: [
...(mdxPluginOptions?.mdxCompileOptions?.rehypePlugins ?? []),
rehypeSlug,
rehypeExternalLinks,
],
},
});

const code = String(await compile(src, mdxLoaderOptions));

return {
code,
// TODO: support source maps
map: null,
};
transform: {
filter: { id: include },
async handler(src, id) {
if (!filter(id)) {
return undefined;
}

const mdxLoaderOptions: CompileOptions = await presets.apply('mdxLoaderOptions', {
...mdxPluginOptions,
mdxCompileOptions: {
providerImportSource: import.meta.resolve('@storybook/addon-docs/mdx-react-shim'),
...mdxPluginOptions?.mdxCompileOptions,
rehypePlugins: [
...(mdxPluginOptions?.mdxCompileOptions?.rehypePlugins ?? []),
rehypeSlug,
rehypeExternalLinks,
],
},
});

const code = String(await compile(src, mdxLoaderOptions));

return {
code,
// TODO: support source maps
map: null,
};
},
},
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,32 @@ export async function injectExportOrderPlugin() {
name: 'storybook:inject-export-order-plugin',
// This should only run after the typescript has been transpiled
enforce: 'post',
async transform(code: string, id: string) {
if (!filter(id)) {
return undefined;
}
transform: {
filter: { id: include },
async handler(code: string, id: string) {
if (!filter(id)) {
return undefined;
}

// TODO: Maybe convert `injectExportOrderPlugin` to function that returns object,
// and run `await init;` once and then call `parse()` without `await`,
// instead of calling `await parse()` every time.
const [, exports] = await parse(code);
// TODO: Maybe convert `injectExportOrderPlugin` to function that returns object,
// and run `await init;` once and then call `parse()` without `await`,
// instead of calling `await parse()` every time.
const [, exports] = await parse(code);

const exportNames = exports.map((e) => code.substring(e.s, e.e));
const exportNames = exports.map((e) => code.substring(e.s, e.e));

if (exportNames.includes('__namedExportsOrder')) {
// user has defined named exports already
return undefined;
}
const s = new MagicString(code);
const orderedExports = exportNames.filter((e) => e !== 'default');
s.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`);
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
if (exportNames.includes('__namedExportsOrder')) {
// user has defined named exports already
return undefined;
}
const s = new MagicString(code);
const orderedExports = exportNames.filter((e) => e !== 'default');
s.append(`;export const __namedExportsOrder = ${JSON.stringify(orderedExports)};`);
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
},
},
} satisfies Plugin;
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export async function storybookExternalGlobalsPlugin(options: Options): Promise<
await init;
const { mergeAlias } = await import('vite');

const globalsList = Object.keys(externals);
const globalsCodeFilter = new RegExp(globalsList.map(escapeKeys).join('|'));

return {
name: 'storybook:external-globals-plugin',
enforce: 'post',
Expand Down Expand Up @@ -88,28 +91,29 @@ export async function storybookExternalGlobalsPlugin(options: Options): Promise<
};
},
// Replace imports with variables destructured from global scope
async transform(code: string, id: string) {
const globalsList = Object.keys(externals);

if (globalsList.every((glob) => !code.includes(glob))) {
return undefined;
}

const [imports] = parse(code);
const src = new MagicString(code);
imports.forEach(({ n: path, ss: startPosition, se: endPosition }) => {
const packageName = path;
if (packageName && globalsList.includes(packageName)) {
const importStatement = src.slice(startPosition, endPosition);
const transformedImport = rewriteImport(importStatement, externals, packageName);
src.update(startPosition, endPosition, transformedImport);
transform: {
filter: { code: globalsCodeFilter },
async handler(code: string, id: string) {
if (globalsList.every((glob) => !code.includes(glob))) {
return undefined;
}
});

return {
code: src.toString(),
map: null,
};
const [imports] = parse(code);
const src = new MagicString(code);
imports.forEach(({ n: path, ss: startPosition, se: endPosition }) => {
const packageName = path;
if (packageName && globalsList.includes(packageName)) {
const importStatement = src.slice(startPosition, endPosition);
const transformedImport = rewriteImport(importStatement, externals, packageName);
src.update(startPosition, endPosition, transformedImport);
}
});

return {
code: src.toString(),
map: null,
};
},
},
} satisfies Plugin;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@ import type { Plugin } from 'vite';
export async function stripStoryHMRBoundary() {
const { createFilter } = await import('vite');

const filter = createFilter(/\.stories\.(tsx?|jsx?|svelte|vue)$/);
const include = /\.stories\.(tsx?|jsx?|svelte|vue)$/;
const filter = createFilter(include);
return {
name: 'storybook:strip-hmr-boundary-plugin',
enforce: 'post',
async transform(src, id) {
if (!filter(id)) {
return undefined;
}
transform: {
filter: { id: include },
async handler(src, id) {
if (!filter(id)) {
return undefined;
}

const s = new MagicString(src);
s.replace(/import\.meta\.hot\.accept\w*/, '(function hmrBoundaryNoop(){})');
const s = new MagicString(src);
s.replace(/import\.meta\.hot\.accept\w*/, '(function hmrBoundaryNoop(){})');

return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
},
},
} satisfies Plugin;
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ export const viteInjectMockerRuntime = (options: {
});
}
},
resolveId(source) {
if (source === ENTRY_PATH) {
return mockerRuntimePath;
}
return undefined;
resolveId: {
filter: { id: /\/vite-inject-mocker-entry\.js/ },
handler(source) {
if (source === ENTRY_PATH) {
return mockerRuntimePath;
}
return undefined;
},
},
transformIndexHtml(html: string) {
const headTag = html.match(/<head[^>]*>/);
Expand Down
21 changes: 12 additions & 9 deletions code/builders/builder-vite/src/plugins/vite-mock/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,19 @@ export function viteMockPlugin(options: MockPluginOptions): Plugin[] {
},
{
name: 'storybook:mock-loader-preview',
transform(code, id) {
if (id === normalizedPreviewConfigPath) {
try {
return rewriteSbMockImportCalls(code);
} catch (e) {
logger.debug(`Could not transform sb.mock(import(...)) calls in ${id}: ${e}`);
return null;
transform: {
filter: { id: normalizedPreviewConfigPath },
handler(code, id) {
if (id === normalizedPreviewConfigPath) {
try {
return rewriteSbMockImportCalls(code);
} catch (e) {
logger.debug(`Could not transform sb.mock(import(...)) calls in ${id}: ${e}`);
return null;
}
}
}
return null;
return null;
},
},
},
];
Expand Down
53 changes: 28 additions & 25 deletions code/frameworks/svelte-vite/src/plugins/svelte-docgen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,31 +116,34 @@ export async function svelteDocgen(): Promise<PluginOption> {

return {
name: 'storybook:svelte-docgen-plugin',
async transform(src: string, id: string) {
if (id.startsWith('\0') || !filter(id)) {
return undefined;
}

const resource = relative(cwd, id);

// Get props information
const docgen = generateDocgen(resource, sourceFileCache);
const data = transformToSvelteDocParserDataItems(docgen);

const componentDoc: SvelteComponentDoc & { keywords?: string[] } = {
data: data,
name: basename(resource),
};

const s = new MagicString(src);
const outputAst = this.parse(src);
const componentName = getComponentName(outputAst as unknown as AST.Program);
s.append(`\n;${componentName}.__docgen = ${JSON.stringify(componentDoc)}`);

return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
transform: {
filter: { id: { include, exclude } },
async handler(src: string, id: string) {
if (id.startsWith('\0') || !filter(id)) {
return undefined;
}

const resource = relative(cwd, id);

// Get props information
const docgen = generateDocgen(resource, sourceFileCache);
const data = transformToSvelteDocParserDataItems(docgen);

const componentDoc: SvelteComponentDoc & { keywords?: string[] } = {
data: data,
name: basename(resource),
};

const s = new MagicString(src);
const outputAst = this.parse(src);
const componentName = getComponentName(outputAst as unknown as AST.Program);
s.append(`\n;${componentName}.__docgen = ${JSON.stringify(componentDoc)}`);

return {
code: s.toString(),
map: s.generateMap({ hires: true, source: id }),
};
},
},
};
}
Loading
Loading