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

Fix experimental_indexers importPath being ignored #26010

Open
wants to merge 3 commits into
base: next
Choose a base branch
from
Open
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
16 changes: 12 additions & 4 deletions code/builders/builder-vite/src/codegen-importfn-script.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as path from 'path';

import type { Options } from 'storybook/internal/types';
import type { Options } from '@storybook/types';

import { listStories } from './list-stories';

Expand All @@ -14,7 +14,7 @@ import { listStories } from './list-stories';
* We want to deal in importPaths relative to the working dir, so we normalize
*/
function toImportPath(relativePath: string) {
return relativePath.startsWith('../') ? relativePath : `./${relativePath}`;
return /\.\.\/|virtual:/.test(relativePath) ? relativePath : `./${relativePath}`;
}

/**
Expand All @@ -38,9 +38,17 @@ async function toImportFn(stories: string[]) {
};

export async function importFn(path) {
return importers[path]();
if (/^virtual:/.test(path)) {
return import(/* @vite-ignore */ '/' + path);
}

if (!(path in importers)) {
throw new Error(\`Storybook generated import script does no have an importer for "\${path}". Existing importers: \${Object.keys(importers)}\`);
}

return importers[path]();
}
`;
`;
}

export async function generateImportFnScriptCode(options: Options) {
Expand Down
34 changes: 25 additions & 9 deletions code/core/src/core-server/utils/StoryIndexGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,11 @@ export class StoryIndexGenerator {
);
return Object.values(cache).flatMap((entry): (IndexEntry | ErrorEntry)[] => {
if (!entry) return [];

if (entry.type === 'docs' || entry.type === 'stories') {
entry.importPath = specifier.importPath;
}

if (entry.type === 'docs') return [entry];
if (entry.type === 'error') return [entry];

Expand Down Expand Up @@ -313,8 +318,20 @@ export class StoryIndexGenerator {
absolutePath: Path,
projectTags: Tag[] = []
): Promise<StoriesCacheEntry | DocsCacheEntry> {
const relativePath = path.relative(this.options.workingDir, absolutePath);
const importPath = slash(normalizeStoryPath(relativePath));
const formatPath = (filePath: string) => {
if (filePath.startsWith('virtual:')) {
return filePath;
}

if (path.isAbsolute(filePath)) {
filePath = path.resolve(this.options.workingDir, filePath);
}

return slash(normalizeStoryPath(filePath));
};

const importPath = formatPath(absolutePath);

const defaultMakeTitle = (userTitle?: string) => {
const title = userOrAutoTitleFromSpecifier(importPath, specifier, userTitle);
invariant(
Expand Down Expand Up @@ -358,8 +375,7 @@ export class StoryIndexGenerator {
metaId: input.metaId,
name,
title,
importPath,
componentPath,
importPath: input.importPath ? formatPath(input.importPath) : importPath,
tags,
};
});
Expand Down Expand Up @@ -450,7 +466,7 @@ export class StoryIndexGenerator {
invariant(
csfEntry,
dedent`Could not find or load CSF file at path "${result.of}" referenced by \`of={}\` in docs file "${relativePath}".

- Does that file exist?
- If so, is it a CSF file (\`.stories.*\`)?
- If so, is it matched by the \`stories\` glob in \`main.js\`?
Expand Down Expand Up @@ -722,15 +738,15 @@ export class StoryIndexGenerator {
} catch (err) {
once.warn(dedent`
Unable to parse tags from project configuration. If defined, tags should be specified inline, e.g.

export default {
tags: ['foo'],
}

---

Received:

${previewCode}
`);
}
Expand Down
41 changes: 41 additions & 0 deletions code/core/src/core-server/utils/__tests__/index-extraction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,47 @@ describe('story extraction', () => {
`);
});

it('leaves virtual paths returned by indexers as is', async () => {
const relativePath = './src/first-nested/deeply/F.stories.js';
const absolutePath = path.join(options.workingDir, relativePath);
const specifier: NormalizedStoriesSpecifier = normalizeStoriesEntry(relativePath, options);

const generator = new StoryIndexGenerator([specifier], {
...options,
indexers: [
{
test: /\.stories\.(m?js|ts)x?$/,
createIndex: async (fileName) => [
{
exportName: 'StoryOne',
type: 'story',
// importPath: "virtual:custom-indexer",
},
],
},
],
});
const result = await generator.extractStories(specifier, absolutePath);

expect(result).toMatchInlineSnapshot(`
{
"dependents": [],
"entries": [
{
"id": "f--story-one",
"importPath": "virtual:custom-indexer",
"metaId": undefined,
"name": "Story One",
"tags": [],
"title": "F",
"type": "story",
},
],
"type": "stories",
}
`);
});

it('auto-generates title from indexer inputs without title', async () => {
const relativePath = './src/first-nested/deeply/F.stories.js';
const absolutePath = path.join(options.workingDir, relativePath);
Expand Down
5 changes: 5 additions & 0 deletions code/core/src/types/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ export interface Presets {
config: TypescriptOptions,
args?: Options
): Promise<TypescriptOptions>;
apply(
extension: 'experimental_indexers',
config?: Indexer[],
args?: any
): Promise<StorybookConfigRaw['experimental_indexers']>;
apply(extension: 'framework', config?: {}, args?: any): Promise<Preset>;
apply(extension: 'babel', config?: {}, args?: any): Promise<any>;
apply(extension: 'swc', config?: {}, args?: any): Promise<any>;
Expand Down
7 changes: 5 additions & 2 deletions code/core/src/types/modules/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,11 @@ export type IndexEntry = StoryIndexEntry | DocsIndexEntry;
* The base input for indexing a story or docs entry.
*/
export type BaseIndexInput = {
/** The file to import from e.g. the story file. */
importPath: Path;
/**
* The file to import to render this story.
* If it's not defined, the path to file that was passed to the indexer will be used.
*/
importPath?: Path;
/** The raw path/package of the file that provides meta.component, if one exists */
rawComponentPath?: Path;
/** The name of the export to import. */
Expand Down
1 change: 1 addition & 0 deletions code/marko
Submodule marko added at 9ac819
Loading