mirror of
https://github.com/storybookjs/storybook.git
synced 2025-04-09 00:19:13 +08:00
Clean code up a little
This commit is contained in:
parent
b2a7949fcc
commit
22db095cdc
@ -12,6 +12,7 @@ import {
|
||||
LoaderFunction,
|
||||
StoryFn,
|
||||
sanitize,
|
||||
storyNameFromExport,
|
||||
} from '@storybook/csf';
|
||||
import {
|
||||
CSFFile,
|
||||
@ -20,7 +21,6 @@ import {
|
||||
Path,
|
||||
StoriesList,
|
||||
combineParameters,
|
||||
NormalizedStoryAnnotations,
|
||||
ModuleExports,
|
||||
} from '@storybook/store';
|
||||
|
||||
@ -316,6 +316,43 @@ Read more here: https://github.com/storybookjs/storybook/blob/master/MIGRATION.m
|
||||
return api;
|
||||
};
|
||||
|
||||
// NOTE: we could potentially share some of this code with the stories.json generation
|
||||
addStoriesFromExports(fileName: Path, fileExports: ModuleExports) {
|
||||
const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports;
|
||||
const { title } = defaultExport || {};
|
||||
if (!title) {
|
||||
throw new Error(
|
||||
`Unexpected default export without title: ${JSON.stringify(fileExports.default)}`
|
||||
);
|
||||
}
|
||||
|
||||
this.csfExports[fileName] = fileExports;
|
||||
|
||||
let exports = namedExports;
|
||||
if (Array.isArray(__namedExportsOrder)) {
|
||||
exports = {};
|
||||
__namedExportsOrder.forEach((name) => {
|
||||
if (namedExports[name]) {
|
||||
exports[name] = namedExports[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
Object.entries(exports).forEach(([key, storyExport]: [string, any]) => {
|
||||
const actualName: string =
|
||||
(typeof storyExport !== 'function' && storyExport.name) ||
|
||||
storyExport.storyName ||
|
||||
storyExport.story?.name ||
|
||||
storyNameFromExport(key);
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const id = storyExport.parameters?.__id || toId(title, actualName);
|
||||
this.storiesList.stories[id] = {
|
||||
name: actualName,
|
||||
title,
|
||||
importPath: fileName,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
// TODO
|
||||
getStorybook: () => [];
|
||||
|
||||
|
52
lib/core-client/src/preview/executeLoadable.ts
Normal file
52
lib/core-client/src/preview/executeLoadable.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { logger } from '@storybook/client-logger';
|
||||
import { ModuleExports } from '@storybook/store';
|
||||
import { Loadable, RequireContext, LoaderFunction } from './types';
|
||||
|
||||
/**
|
||||
* Executes a Loadable (function that returns exports or require context(s))
|
||||
* and returns a map of filename => module exports
|
||||
*
|
||||
* @param loadable Loadable
|
||||
* @returns Map<string, ModuleExports>
|
||||
*/
|
||||
export function executeLoadable(loadable: Loadable) {
|
||||
let reqs = null;
|
||||
// todo discuss / improve type check
|
||||
if (Array.isArray(loadable)) {
|
||||
reqs = loadable;
|
||||
} else if ((loadable as RequireContext).keys) {
|
||||
reqs = [loadable as RequireContext];
|
||||
}
|
||||
|
||||
let exportsMap = new Map<string, ModuleExports>();
|
||||
if (reqs) {
|
||||
reqs.forEach((req) => {
|
||||
req.keys().forEach((filename: string) => {
|
||||
try {
|
||||
const fileExports = req(filename) as ModuleExports;
|
||||
exportsMap.set(
|
||||
typeof req.resolve === 'function' ? req.resolve(filename) : filename,
|
||||
fileExports
|
||||
);
|
||||
} catch (error) {
|
||||
logger.warn(`Unexpected error while loading ${filename}: ${error}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const exported = (loadable as LoaderFunction)();
|
||||
if (Array.isArray(exported) && exported.every((obj) => obj.default != null)) {
|
||||
exportsMap = new Map(
|
||||
exported.map((fileExports, index) => [`exports-map-${index}`, fileExports])
|
||||
);
|
||||
} else if (exported) {
|
||||
logger.warn(
|
||||
`Loader function passed to 'configure' should return void or an array of module exports that all contain a 'default' export. Received: ${JSON.stringify(
|
||||
exported
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return exportsMap;
|
||||
}
|
@ -141,6 +141,7 @@ describe('start', () => {
|
||||
expect.objectContaining({
|
||||
storyContext: expect.objectContaining({
|
||||
parameters: expect.objectContaining({
|
||||
framework: 'test',
|
||||
param: 'global',
|
||||
}),
|
||||
}),
|
||||
|
@ -1,55 +1,13 @@
|
||||
import { ClientApi } from '@storybook/client-api';
|
||||
import { ClientApi, ModuleExports } from '@storybook/client-api';
|
||||
import { WebGlobalAnnotations, WebPreview } from '@storybook/web-preview';
|
||||
import { Framework, toId, storyNameFromExport } from '@storybook/csf';
|
||||
import { logger } from '@storybook/client-logger';
|
||||
import createChannel from '@storybook/channel-postmessage';
|
||||
import { addons } from '@storybook/addons';
|
||||
import Events from '@storybook/core-events';
|
||||
import { Path, ModuleExports } from '@storybook/store';
|
||||
import { Path } from '@storybook/store';
|
||||
|
||||
import { Loadable, RequireContext, LoaderFunction } from './types';
|
||||
|
||||
function runLoadable(loadable: Loadable) {
|
||||
let reqs = null;
|
||||
// todo discuss / improve type check
|
||||
if (Array.isArray(loadable)) {
|
||||
reqs = loadable;
|
||||
} else if ((loadable as RequireContext).keys) {
|
||||
reqs = [loadable as RequireContext];
|
||||
}
|
||||
|
||||
let exportsMap = new Map<string, ModuleExports>();
|
||||
if (reqs) {
|
||||
reqs.forEach((req) => {
|
||||
req.keys().forEach((filename: string) => {
|
||||
try {
|
||||
const fileExports = req(filename) as ModuleExports;
|
||||
exportsMap.set(
|
||||
typeof req.resolve === 'function' ? req.resolve(filename) : filename,
|
||||
fileExports
|
||||
);
|
||||
} catch (error) {
|
||||
logger.warn(`Unexpected error while loading ${filename}: ${error}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const exported = (loadable as LoaderFunction)();
|
||||
if (Array.isArray(exported) && exported.every((obj) => obj.default != null)) {
|
||||
exportsMap = new Map(
|
||||
exported.map((fileExports, index) => [`exports-map-${index}`, fileExports])
|
||||
);
|
||||
} else if (exported) {
|
||||
logger.warn(
|
||||
`Loader function passed to 'configure' should return void or an array of module exports that all contain a 'default' export. Received: ${JSON.stringify(
|
||||
exported
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return exportsMap;
|
||||
}
|
||||
import { Loadable } from './types';
|
||||
import { executeLoadable } from './executeLoadable';
|
||||
|
||||
export function start<TFramework extends Framework>(
|
||||
render: WebGlobalAnnotations<TFramework>['renderToDOM'],
|
||||
@ -67,49 +25,18 @@ export function start<TFramework extends Framework>(
|
||||
raw: (): void => {},
|
||||
|
||||
clientApi,
|
||||
// TODO -- add framework to globalAnnotations.parameters?
|
||||
configure(framework: string, loadable: Loadable, m?: NodeModule) {
|
||||
clientApi.addParameters({ framework });
|
||||
|
||||
const getGlobalAnnotations = () => {
|
||||
// TODO
|
||||
// clientApi.resetGlobalAnnotations();
|
||||
|
||||
const exportsMap = runLoadable(loadable);
|
||||
const exportsMap = executeLoadable(loadable);
|
||||
Array.from(exportsMap.entries())
|
||||
.filter(([, fileExports]) => !!fileExports.default)
|
||||
.forEach(([fileName, fileExports]) => {
|
||||
const { default: defaultExport, __namedExportsOrder, ...namedExports } = fileExports;
|
||||
const { title } = defaultExport || {};
|
||||
if (!title) {
|
||||
throw new Error(
|
||||
`Unexpected default export without title: ${JSON.stringify(fileExports.default)}`
|
||||
);
|
||||
}
|
||||
|
||||
clientApi.csfExports[fileName] = fileExports;
|
||||
|
||||
let exports = namedExports;
|
||||
if (Array.isArray(__namedExportsOrder)) {
|
||||
exports = {};
|
||||
__namedExportsOrder.forEach((name) => {
|
||||
if (namedExports[name]) {
|
||||
exports[name] = namedExports[name];
|
||||
}
|
||||
});
|
||||
}
|
||||
Object.entries(exports).forEach(([key, storyExport]: [string, any]) => {
|
||||
const actualName: string =
|
||||
(typeof storyExport !== 'function' && storyExport.name) ||
|
||||
storyExport.storyName ||
|
||||
storyExport.story?.name ||
|
||||
storyNameFromExport(key);
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
const id = storyExport.parameters?.__id || toId(title, actualName);
|
||||
clientApi.storiesList.stories[id] = {
|
||||
name: actualName,
|
||||
title,
|
||||
importPath: fileName,
|
||||
};
|
||||
});
|
||||
clientApi.addStoriesFromExports(fileName, fileExports);
|
||||
});
|
||||
|
||||
return {
|
||||
|
Loading…
x
Reference in New Issue
Block a user