Merge pull request #10159 from storybookjs/fix/generated-load-order

FIX error of load order when using configure in preview|config.js
This commit is contained in:
Norbert de Langen 2020-03-20 11:53:49 +01:00 committed by GitHub
commit 1dfb84ec1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 112 additions and 12 deletions

View File

@ -23,7 +23,9 @@ addParameters({
// force full reload to not re-register web components
const req = require.context('../stories', true, /\.stories\.(js|mdx)$/);
configure(req, module);
if (module.hot) {
module.hot.accept(req.id, () => {
const currentLocationHref = window.location.href;

View File

@ -98,6 +98,7 @@
"semver": "^6.0.0",
"serve-favicon": "^2.5.0",
"shelljs": "^0.8.3",
"stable": "^0.1.8",
"style-loader": "^1.0.0",
"terser-webpack-plugin": "^2.3.4",
"ts-dedent": "^1.1.1",

View File

@ -1,5 +1,33 @@
import path from 'path';
import { logger } from '@storybook/node-logger';
import stable from 'stable';
import { loadPreviewOrConfigFile } from '../utils/load-preview-or-config-file';
export const sortEntries = entries => {
const isGenerated = /generated-(config|other)-entry/;
const isGeneratedConfig = /(?:preview|config)\..+-generated-config-entry/;
return stable(entries.slice(0), (a, b) => {
// preview & config can call configure which should always happen AFTER all global decorators & args are set
switch (true) {
case !!a.match(isGeneratedConfig) && !!b.match(isGenerated): {
return 1;
}
case !!b.match(isGeneratedConfig) && !!a.match(isGenerated): {
return -1;
}
default: {
return 0;
}
}
});
};
const getMainConfigs = options => {
const previewPath = loadPreviewOrConfigFile(options);
return previewPath ? [previewPath] : [];
};
export async function createPreviewEntry(options) {
const { configDir, presets } = options;
@ -9,18 +37,24 @@ export async function createPreviewEntry(options) {
path.resolve(path.join(configDir, 'storybook-init-framework-entry.js')),
];
const configs = await presets.apply('config', [], options);
const configs = getMainConfigs(options);
const other = await presets.apply('config', [], options);
const stories = await presets.apply('stories', [], options);
if (configs && configs.length) {
if (configs.length) {
logger.info(`=> Loading config/preview file in "${configDir}".`);
entries.push(...configs.map(filename => `${filename}-generated-config-entry.js`));
}
if (other && other.length) {
logger.info(`=> Loading config/preview file in "${configDir}".`);
entries.push(...other.map(filename => `${filename}-generated-other-entry.js`));
}
if (stories && stories.length) {
logger.info(`=> Adding stories defined in "${path.join(configDir, 'main.js')}".`);
entries.push(path.resolve(path.join(configDir, `generated-stories-entry.js`)));
}
return entries;
return sortEntries(entries);
}

View File

@ -0,0 +1,68 @@
import { sortEntries } from './entries';
describe('sortEntries', () => {
it('should do nothing', () => {
const input = ['a', 'b', 'c', 'aa', 'cc', '123', '8000'];
const output = sortEntries(input);
expect(output).toEqual(['a', 'b', 'c', 'aa', 'cc', '123', '8000']);
});
it('should move preview-type generated-config entries after all other generated entries', () => {
const input = [
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/common/polyfills.js',
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/preview/globals.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/web-components-kitchen-sink/.storybook/storybook-init-framework-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/web-components-kitchen-sink/.storybook/preview.js-generated-config-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/common/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/web-components/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/actions/dist/preset/addArgs.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/links/dist/preset/addDecorator.js-generated-other-entry.js',
];
const output = sortEntries(input);
expect(output).toEqual([
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/common/polyfills.js',
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/preview/globals.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/web-components-kitchen-sink/.storybook/storybook-init-framework-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/common/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/web-components/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/actions/dist/preset/addArgs.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/links/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/web-components-kitchen-sink/.storybook/preview.js-generated-config-entry.js',
]);
});
it('should move stories-type all other generated entries', () => {
const input = [
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/common/polyfills.js',
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/preview/globals.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/official-storybook/storybook-init-framework-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/official-storybook/preview.js-generated-config-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/common/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/react/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/actions/dist/preset/addArgs.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/links/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/queryparams/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/official-storybook/generated-stories-entry.js',
];
const output = sortEntries(input);
expect(output).toEqual([
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/common/polyfills.js',
'/Users/dev/Projects/GitHub/storybook/core/lib/core/dist/server/preview/globals.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/official-storybook/storybook-init-framework-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/common/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/docs/dist/frameworks/react/config.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/actions/dist/preset/addArgs.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/links/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/knobs/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/a11y/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/addons/queryparams/dist/preset/addDecorator.js-generated-other-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/official-storybook/preview.js-generated-config-entry.js',
'/Users/dev/Projects/GitHub/storybook/core/examples/official-storybook/generated-stories-entry.js',
]);
});
});

View File

@ -49,7 +49,7 @@ export default ({
[frameworkInitEntry]: `import '@storybook/${framework}';`,
};
entries.forEach(entryFilename => {
const match = entryFilename.match(/(.*)-generated-config-entry.js$/);
const match = entryFilename.match(/(.*)-generated-(config|other)-entry.js$/);
if (match) {
const configFilename = match[1];
virtualModuleMapping[entryFilename] = `

View File

@ -1,5 +1,3 @@
import { loadPreviewOrConfigFile } from '../utils/load-preview-or-config-file';
import webpackConfig from './iframe-webpack.config';
import { createPreviewEntry } from './entries';
@ -19,9 +17,4 @@ export const entries = async (_, options) => {
return result;
};
export const config = async (_, options) => {
const previewPath = loadPreviewOrConfigFile(options);
return previewPath ? [previewPath] : [];
};
export * from '../common/common-preset';

View File

@ -148,7 +148,9 @@ const handleExamples = async deployables => {
const out = p(['built-storybooks', d]);
const cwd = p(['examples', d]);
await exec(`yarn`, [`build-storybook`, `--output-dir=${out}`, '--quiet'], { cwd });
await exec(`yarn`, [`build-storybook`, `--output-dir=${out}`, '--quiet'], {
cwd,
});
logger.log('-------');
logger.log(`${d} built`);