Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX error of load order when using configure in preview|config.js #10159

Merged
merged 12 commits into from
Mar 20, 2020
2 changes: 2 additions & 0 deletions examples/web-components-kitchen-sink/.storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions lib/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
41 changes: 38 additions & 3 deletions lib/core/src/server/preview/entries.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
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) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"preview & config can call configure which should always happen AFTER all global decorators & args are set." - better explanation

// we want this order to order generated entries so the ones that call configure appear LAST
// whilst keeping the order of non-generated entries in the order they appear

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;
Expand All @@ -9,18 +38,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);
}
68 changes: 68 additions & 0 deletions lib/core/src/server/preview/entries.test.js
Original file line number Diff line number Diff line change
@@ -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', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is after missing from this sentence?

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',
]);
});
});
2 changes: 1 addition & 1 deletion lib/core/src/server/preview/iframe-webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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] = `
Expand Down
7 changes: 0 additions & 7 deletions lib/core/src/server/preview/preview-preset.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { loadPreviewOrConfigFile } from '../utils/load-preview-or-config-file';

import webpackConfig from './iframe-webpack.config';
import { createPreviewEntry } from './entries';

Expand All @@ -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';
4 changes: 3 additions & 1 deletion scripts/build-storybooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', '--debug-webpack'], {
cwd,
});

logger.log('-------');
logger.log(`✅ ${d} built`);
Expand Down