Skip to content

Commit

Permalink
Add a to-importFn utility
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeasday committed Aug 10, 2021
1 parent d758c4e commit 0b77e47
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
10 changes: 3 additions & 7 deletions lib/builder-webpack4/src/preview/iframe-webpack.config.ts
Expand Up @@ -25,6 +25,7 @@ import {
nodeModulesPaths,
Options,
NormalizedStoriesEntry,
toImportFn,
} from '@storybook/core-common';
import { createBabelLoader } from './babel-loader-preview';

Expand Down Expand Up @@ -85,13 +86,7 @@ export default async ({

// Allows for custom frameworks that are not published under the @storybook namespace
const virtualModuleMapping = {
[storiesPath]: dedent`
// TODO -- non-hardcoded importFn
export const importFn = async (path) => {
console.log('importFn ' + path);
return import('./src/' + path.replace(/^src\//, ''));
};
`,
[storiesPath]: toImportFn(stories),
[configEntryPath]: dedent`
import { composeConfigs } from '@storybook/core-client/dist/esm/preview/new/composeConfigs';
import { WebPreview } from '@storybook/core-client/dist/esm/preview/new/WebPreview';
Expand Down Expand Up @@ -133,6 +128,7 @@ export default async ({
`,
};

console.log(virtualModuleMapping[storiesPath]);
console.log(virtualModuleMapping[configEntryPath]);
// if (stories) {
// const storiesFilename = path.resolve(path.join(configDir, `generated-stories-entry.js`));
Expand Down
1 change: 1 addition & 0 deletions lib/core-common/src/index.ts
Expand Up @@ -23,5 +23,6 @@ export * from './utils/validate-configuration-files';
export * from './utils/to-require-context';
export * from './utils/has-dotenv';
export * from './utils/normalize-stories';
export * from './utils/to-importFn';

export * from './types';
46 changes: 46 additions & 0 deletions lib/core-common/src/utils/to-importFn.ts
@@ -0,0 +1,46 @@
import globBase from 'glob-base';

This comment has been minimized.

Copy link
@shilman

shilman Aug 10, 2021

Member

we just removed glob-base here #15399

This comment has been minimized.

Copy link
@tmeasday

tmeasday Aug 10, 2021

Author Member

Ok, I'll merge that in I guess

import { makeRe } from 'micromatch';
import dedent from 'ts-dedent';

import type { NormalizedStoriesEntry } from '../types';

export function toImportFnPart(entry: NormalizedStoriesEntry) {
const { base } = globBase(entry.glob);
const regex = makeRe(entry.glob, { fastpaths: false, noglobstar: false, bash: false });

const webpackIncludeRegex = new RegExp(regex.source.substring(1));

// NOTE: `base` looks like './src' but `path`, (and what micromatch expects)
// is something that starts with `src/`. So to strip off base from path, we
// need to drop `base.length - 1` chars.
return dedent`
async (path) => {
if (!${regex}.exec(path)) {
return;
}
const remainder = path.substring(${base.length - 1});
return import(
/* webpackInclude: ${webpackIncludeRegex} */
'${base}/' + remainder
);
}
`;
}

export function toImportFn(stories: NormalizedStoriesEntry[]) {
return dedent`
const importers = [
${stories.map(toImportFnPart).join(',\n')}
];
export async function importFn(path) {
for (let i = 0; i < importers.length; i++) {

This comment has been minimized.

Copy link
@shilman

shilman Aug 10, 2021

Member

it looks like this is going through the importers one by one until it finds a "hit". @tmeasday is that correct? can you explain the logic behind it?

This comment has been minimized.

Copy link
@tmeasday

tmeasday Aug 10, 2021

Author Member

So each importer corresponds to a glob, eg. ../src/**/*.stories.js.

We need to find the importer that is right for the path currently being imported (e.g. ../src/bar/foo/foo.stories.js). Each importer either returns false or does the import and returns the file's exports.

const moduleExports = await importers[i](path);
if (moduleExports) {
return moduleExports;
}
}
}
`;
}

0 comments on commit 0b77e47

Please sign in to comment.