Skip to content

Commit 9b55e8e

Browse files
authored
Merge pull request #28941 from tobiasdiez/vite-remove-fs
Vite: Don't prefix story import with `@fs`
2 parents f8a1255 + 8936c5f commit 9b55e8e

File tree

7 files changed

+108
-18
lines changed

7 files changed

+108
-18
lines changed

code/builders/builder-vite/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@
5353
"es-module-lexer": "^1.5.0",
5454
"find-cache-dir": "^3.0.0",
5555
"glob": "^10.0.0",
56+
"knitwork": "^1.1.0",
5657
"magic-string": "^0.30.0",
58+
"pathe": "^1.1.2",
5759
"polka": "^1.0.0-next.28",
5860
"sirv": "^2.0.4",
5961
"slash": "^5.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { beforeEach, describe, expect, it, vi } from 'vitest';
2+
3+
import { toImportFn } from './codegen-importfn-script';
4+
5+
describe('toImportFn', () => {
6+
it('should correctly map story paths to import functions for absolute paths on Linux', async () => {
7+
const root = '/absolute/path';
8+
const stories = ['/absolute/path/to/story1.js', '/absolute/path/to/story2.js'];
9+
10+
const result = await toImportFn(root, stories);
11+
12+
expect(result).toMatchInlineSnapshot(`
13+
"const importers = {
14+
"./to/story1.js": () => import("/absolute/path/to/story1.js"),
15+
"./to/story2.js": () => import("/absolute/path/to/story2.js")
16+
};
17+
18+
export async function importFn(path) {
19+
return await importers[path]();
20+
}"
21+
`);
22+
});
23+
24+
it('should correctly map story paths to import functions for absolute paths on Windows', async () => {
25+
const root = 'C:\\absolute\\path';
26+
const stories = ['C:\\absolute\\path\\to\\story1.js', 'C:\\absolute\\path\\to\\story2.js'];
27+
28+
const result = await toImportFn(root, stories);
29+
30+
expect(result).toMatchInlineSnapshot(`
31+
"const importers = {
32+
"./to/story1.js": () => import("C:/absolute/path/to/story1.js"),
33+
"./to/story2.js": () => import("C:/absolute/path/to/story2.js")
34+
};
35+
36+
export async function importFn(path) {
37+
return await importers[path]();
38+
}"
39+
`);
40+
});
41+
42+
it('should handle an empty array of stories', async () => {
43+
const root = '/absolute/path';
44+
const stories: string[] = [];
45+
46+
const result = await toImportFn(root, stories);
47+
48+
expect(result).toMatchInlineSnapshot(`
49+
"const importers = {};
50+
51+
export async function importFn(path) {
52+
return await importers[path]();
53+
}"
54+
`);
55+
});
56+
});
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { relative } from 'node:path';
2-
31
import type { Options } from 'storybook/internal/types';
42

3+
import { genDynamicImport, genImport, genObjectFromRawEntries } from 'knitwork';
4+
import { normalize, relative } from 'pathe';
5+
import { dedent } from 'ts-dedent';
6+
57
import { listStories } from './list-stories';
68

79
/**
@@ -21,34 +23,33 @@ function toImportPath(relativePath: string) {
2123
/**
2224
* This function takes an array of stories and creates a mapping between the stories' relative paths
2325
* to the working directory and their dynamic imports. The import is done in an asynchronous
24-
* function to delay loading. It then creates a function, `importFn(path)`, which resolves a path to
25-
* an import function and this is called by Storybook to fetch a story dynamically when needed.
26+
* function to delay loading and to allow Vite to split the code into smaller chunks. It then
27+
* creates a function, `importFn(path)`, which resolves a path to an import function and this is
28+
* called by Storybook to fetch a story dynamically when needed.
2629
*
2730
* @param stories An array of absolute story paths.
2831
*/
29-
async function toImportFn(stories: string[]) {
30-
const { normalizePath } = await import('vite');
32+
export async function toImportFn(root: string, stories: string[]) {
3133
const objectEntries = stories.map((file) => {
32-
const relativePath = normalizePath(relative(process.cwd(), file));
34+
const relativePath = relative(root, file);
3335

34-
return ` '${toImportPath(relativePath)}': async () => import('/@fs/${file}')`;
36+
return [toImportPath(relativePath), genDynamicImport(normalize(file))] as [string, string];
3537
});
3638

37-
return `
38-
const importers = {
39-
${objectEntries.join(',\n')}
40-
};
39+
return dedent`
40+
const importers = ${genObjectFromRawEntries(objectEntries)};
4141
4242
export async function importFn(path) {
43-
return importers[path]();
43+
return await importers[path]();
4444
}
4545
`;
4646
}
4747

48-
export async function generateImportFnScriptCode(options: Options) {
48+
export async function generateImportFnScriptCode(options: Options): Promise<string> {
4949
// First we need to get an array of stories and their absolute paths.
5050
const stories = await listStories(options);
5151

5252
// We can then call toImportFn to create a function that can be used to load each story dynamically.
53-
return (await toImportFn(stories)).trim();
53+
// eslint-disable-next-line @typescript-eslint/return-await
54+
return await toImportFn(options.projectRoot || process.cwd(), stories);
5455
}

code/builders/builder-vite/src/vite-config.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,18 @@ export async function commonConfig(
5353

5454
const { viteConfigPath } = await getBuilderOptions<BuilderOptions>(options);
5555

56-
const projectRoot = resolve(options.configDir, '..');
56+
options.projectRoot = options.projectRoot || resolve(options.configDir, '..');
5757

5858
// I destructure away the `build` property from the user's config object
5959
// I do this because I can contain config that breaks storybook, such as we had in a lit project.
6060
// If the user needs to configure the `build` they need to do so in the viteFinal function in main.js.
6161
const { config: { build: buildProperty = undefined, ...userConfig } = {} } =
62-
(await loadConfigFromFile(configEnv, viteConfigPath, projectRoot)) ?? {};
62+
(await loadConfigFromFile(configEnv, viteConfigPath, options.projectRoot)) ?? {};
6363

6464
const sbConfig: InlineConfig = {
6565
configFile: false,
6666
cacheDir: resolvePathInStorybookCache('sb-vite', options.cacheKey),
67-
root: projectRoot,
67+
root: options.projectRoot,
6868
// Allow storybook deployed as subfolder. See https://github.com/storybookjs/builder-vite/issues/238
6969
base: './',
7070
plugins: await pluginConfig(options),

code/core/src/types/modules/core-common.ts

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ export interface BuilderOptions {
194194
ignorePreview?: boolean;
195195
cache?: FileSystemCache;
196196
configDir: string;
197+
projectRoot?: string;
197198
docsMode?: boolean;
198199
features?: StorybookConfigRaw['features'];
199200
versionCheck?: VersionCheck;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "nuxt-vite/default-ts",
3+
"$schema": "../../node_modules/nx/schemas/project-schema.json",
4+
"projectType": "application",
5+
"implicitDependencies": [
6+
"storybook",
7+
"core",
8+
"addon-essentials",
9+
"addon-interactions",
10+
"addon-links",
11+
"addon-onboarding",
12+
"blocks",
13+
"vue3-vite"
14+
],
15+
"targets": {
16+
"sandbox": {},
17+
"sb:dev": {},
18+
"sb:build": {}
19+
},
20+
"tags": ["ci:normal", "ci:merged", "ci:daily"]
21+
}

code/yarn.lock

+9
Original file line numberDiff line numberDiff line change
@@ -6172,7 +6172,9 @@ __metadata:
61726172
es-module-lexer: "npm:^1.5.0"
61736173
find-cache-dir: "npm:^3.0.0"
61746174
glob: "npm:^10.0.0"
6175+
knitwork: "npm:^1.1.0"
61756176
magic-string: "npm:^0.30.0"
6177+
pathe: "npm:^1.1.2"
61766178
polka: "npm:^1.0.0-next.28"
61776179
sirv: "npm:^2.0.4"
61786180
slash: "npm:^5.0.0"
@@ -19330,6 +19332,13 @@ __metadata:
1933019332
languageName: node
1933119333
linkType: hard
1933219334

19335+
"knitwork@npm:^1.1.0":
19336+
version: 1.1.0
19337+
resolution: "knitwork@npm:1.1.0"
19338+
checksum: 10c0/e23c679d4ded01890ab2669ccde2e85e4d7e6ba327b1395ff657f8067c7d73dc134fc8cd8188c653de4a687be7fa9c130bd36c3e2f76d8685e8b97ff8b30779c
19339+
languageName: node
19340+
linkType: hard
19341+
1933319342
"language-subtag-registry@npm:^0.3.20":
1933419343
version: 0.3.22
1933519344
resolution: "language-subtag-registry@npm:0.3.22"

0 commit comments

Comments
 (0)