1
- import { relative } from 'node:path' ;
2
-
3
1
import type { Options } from 'storybook/internal/types' ;
4
2
3
+ import { genDynamicImport , genImport , genObjectFromRawEntries } from 'knitwork' ;
4
+ import { normalize , relative } from 'pathe' ;
5
+ import { dedent } from 'ts-dedent' ;
6
+
5
7
import { listStories } from './list-stories' ;
6
8
7
9
/**
@@ -21,34 +23,33 @@ function toImportPath(relativePath: string) {
21
23
/**
22
24
* This function takes an array of stories and creates a mapping between the stories' relative paths
23
25
* 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.
26
29
*
27
30
* @param stories An array of absolute story paths.
28
31
*/
29
- async function toImportFn ( stories : string [ ] ) {
30
- const { normalizePath } = await import ( 'vite' ) ;
32
+ export async function toImportFn ( root : string , stories : string [ ] ) {
31
33
const objectEntries = stories . map ( ( file ) => {
32
- const relativePath = normalizePath ( relative ( process . cwd ( ) , file ) ) ;
34
+ const relativePath = relative ( root , file ) ;
33
35
34
- return ` ' ${ toImportPath ( relativePath ) } ': async () => import('/@fs/ ${ file } ')` ;
36
+ return [ toImportPath ( relativePath ) , genDynamicImport ( normalize ( file ) ) ] as [ string , string ] ;
35
37
} ) ;
36
38
37
- return `
38
- const importers = {
39
- ${ objectEntries . join ( ',\n' ) }
40
- };
39
+ return dedent `
40
+ const importers = ${ genObjectFromRawEntries ( objectEntries ) } ;
41
41
42
42
export async function importFn(path) {
43
- return importers[path]();
43
+ return await importers[path]();
44
44
}
45
45
` ;
46
46
}
47
47
48
- export async function generateImportFnScriptCode ( options : Options ) {
48
+ export async function generateImportFnScriptCode ( options : Options ) : Promise < string > {
49
49
// First we need to get an array of stories and their absolute paths.
50
50
const stories = await listStories ( options ) ;
51
51
52
52
// 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 ) ;
54
55
}
0 commit comments