From e585b5ee652ce421d21101f808d22504f638166a Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 15 Jun 2020 11:24:54 +0200 Subject: [PATCH 1/6] FIX https://github.com/storybookjs/storybook/issues/9819 REMOVE custom webpack for official example --- examples/official-storybook/main.ts | 50 ----------------------- lib/core/src/server/presets.js | 62 ++++++++++++++++------------- 2 files changed, 34 insertions(+), 78 deletions(-) diff --git a/examples/official-storybook/main.ts b/examples/official-storybook/main.ts index c5ebd19e352c..ce7134b34955 100644 --- a/examples/official-storybook/main.ts +++ b/examples/official-storybook/main.ts @@ -27,54 +27,4 @@ module.exports = { '@storybook/addon-queryparams', ], logLevel: 'debug', - webpackFinal: async (config, { configType }) => ({ - ...config, - module: { - ...config.module, - rules: [ - ...config.module.rules.slice(1), - { - test: /\.(mjs|jsx?|tsx?)$/, - use: [ - { - loader: 'babel-loader', - options: { - cacheDirectory: `.cache/storybook`, - presets: [ - [ - '@babel/preset-env', - { shippedProposals: true, useBuiltIns: 'usage', corejs: 3 }, - ], - '@babel/preset-typescript', - configType === 'PRODUCTION' && [ - 'babel-preset-minify', - { builtIns: false, mangle: false }, - ], - '@babel/preset-react', - '@babel/preset-flow', - ].filter(Boolean), - plugins: [ - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-proposal-class-properties', - '@babel/plugin-syntax-dynamic-import', - ['babel-plugin-emotion', { sourceMap: true, autoLabel: true }], - 'babel-plugin-macros', - 'babel-plugin-add-react-displayname', - [ - 'babel-plugin-react-docgen', - { DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES' }, - ], - ], - }, - }, - ], - exclude: [/node_modules/, /dist/], - }, - ], - }, - resolve: { - ...config.resolve, - extensions: [...(config.resolve.extensions || []), '.ts', '.tsx'], - }, - }), } as StorybookConfig; diff --git a/lib/core/src/server/presets.js b/lib/core/src/server/presets.js index 16eff965499c..5a24fe734ab0 100644 --- a/lib/core/src/server/presets.js +++ b/lib/core/src/server/presets.js @@ -43,7 +43,7 @@ const resolvePresetFunction = (input, presetOptions, storybookOptions) => { const isLocalFileImport = (packageName) => fs.existsSync(packageName); /** - * Parse an addon into either a managerEntry or a preset. Throw on invalid input. + * Parse an addon into either a managerEntries or a preset. Throw on invalid input. * * Valid inputs: * - '@storybook/addon-actions/register' @@ -94,29 +94,27 @@ export const resolveAddonName = (name) => { return { name, type: 'presets' }; }; -export const splitAddons = (addons) => { - return addons.reduce( - (acc, item) => { - try { - if (isObject(item)) { - const { name } = resolveAddonName(item.name); - acc.presets.push({ ...item, name }); - } else { - const { name, type } = resolveAddonName(item); - acc[type].push(name); - } - } catch (err) { - logger.error( - `Addon value should end in /register OR it should be a valid preset https://storybook.js.org/docs/presets/introduction/\n${item}` - ); - } - return acc; - }, - { - managerEntries: [], - presets: [], +export const map = (item, index) => { + try { + if (isObject(item)) { + const { name } = resolveAddonName(item.name); + return { ...item, name }; + } + const { name, type } = resolveAddonName(item); + if (type === 'managerEntries') { + return { + name: `${name}_${index}additionalManagerEntries`, + type, + managerEntries: [name], + }; } - ); + return resolveAddonName(name); + } catch (err) { + logger.error( + `Addon value should end in /register OR it should be a valid preset https://storybook.js.org/docs/presets/introduction/\n${item}` + ); + } + return undefined; }; function interopRequireDefault(filePath) { @@ -129,11 +127,21 @@ function interopRequireDefault(filePath) { return isES6DefaultExported ? result.default : result; } +function getContent(input) { + if (input.type === 'managerEntries') { + return input; + } + const name = input.name ? input.name : input; + + return interopRequireDefault(name); +} + function loadPreset(input, level, storybookOptions) { try { const name = input.name ? input.name : input; const presetOptions = input.options ? input.options : {}; - let contents = interopRequireDefault(name); + + let contents = getContent(input); if (typeof contents === 'function') { // allow the export of a preset to be a function, that gets storybookOptions @@ -151,11 +159,9 @@ function loadPreset(input, level, storybookOptions) { const subPresets = resolvePresetFunction(presetsInput, presetOptions, storybookOptions); const subAddons = resolvePresetFunction(addonsInput, presetOptions, storybookOptions); - const { managerEntries, presets } = splitAddons(subAddons); - return [ - ...loadPresets([...subPresets, ...presets], level + 1, storybookOptions), - { name: `${name}_additionalManagerEntries`, preset: { managerEntries } }, + ...loadPresets([...subPresets], level + 1, storybookOptions), + ...loadPresets([...subAddons.map(map)].filter(Boolean), level + 1, storybookOptions), { name, preset: rest, From 858227b77aba360592039c8c37e61f4baeab8bcf Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 16 Jun 2020 11:36:07 +0200 Subject: [PATCH 2/6] FIX versions --- lib/api/src/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/src/version.ts b/lib/api/src/version.ts index fc598fd00651..6cd5db8e8dcf 100644 --- a/lib/api/src/version.ts +++ b/lib/api/src/version.ts @@ -1 +1 @@ -export const version = '6.0.0-beta.28'; +export const version = '6.0.0-beta.29'; From 288e846423371ace3304ba1f2c50419c1e23832b Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 16 Jun 2020 11:39:29 +0200 Subject: [PATCH 3/6] FIX tests --- lib/core/src/server/presets.js | 12 ++- lib/core/src/server/presets.test.js | 140 ++++++++++++++++++---------- 2 files changed, 97 insertions(+), 55 deletions(-) diff --git a/lib/core/src/server/presets.js b/lib/core/src/server/presets.js index 5a24fe734ab0..2836d85d2505 100644 --- a/lib/core/src/server/presets.js +++ b/lib/core/src/server/presets.js @@ -94,7 +94,7 @@ export const resolveAddonName = (name) => { return { name, type: 'presets' }; }; -export const map = (item, index) => { +export const map = (item) => { try { if (isObject(item)) { const { name } = resolveAddonName(item.name); @@ -103,7 +103,7 @@ export const map = (item, index) => { const { name, type } = resolveAddonName(item); if (type === 'managerEntries') { return { - name: `${name}_${index}additionalManagerEntries`, + name: `${name}_additionalManagerEntries`, type, managerEntries: [name], }; @@ -119,7 +119,8 @@ export const map = (item, index) => { function interopRequireDefault(filePath) { // eslint-disable-next-line global-require,import/no-dynamic-require - const result = require(`${filePath}`); + const result = require(filePath); + // console.log(filePath, result); const isES6DefaultExported = typeof result === 'object' && result !== null && typeof result.default !== 'undefined'; @@ -129,14 +130,15 @@ function interopRequireDefault(filePath) { function getContent(input) { if (input.type === 'managerEntries') { - return input; + const { type, name, ...rest } = input; + return rest; } const name = input.name ? input.name : input; return interopRequireDefault(name); } -function loadPreset(input, level, storybookOptions) { +export function loadPreset(input, level, storybookOptions) { try { const name = input.name ? input.name : input; const presetOptions = input.options ? input.options : {}; diff --git a/lib/core/src/server/presets.test.js b/lib/core/src/server/presets.test.js index 711825a2528f..23c5ee24c97a 100644 --- a/lib/core/src/server/presets.test.js +++ b/lib/core/src/server/presets.test.js @@ -21,8 +21,14 @@ jest.mock('./utils/resolve-file', () => ({ resolveFile: (name) => { const KNOWN_FILES = [ '@storybook/addon-actions/register', - '@storybook/addon-knobs/register', + '@storybook/addon-docs', '@storybook/addon-docs/preset', + '@storybook/addon-knobs', + '@storybook/addon-notes/register-panel', + '@storybook/preset-typescript', + 'addon-bar/preset.js', + 'addon-baz/register.js', + 'addon-foo/register.js', ]; if (KNOWN_FILES.includes(name)) { return name; @@ -343,8 +349,8 @@ describe('resolveAddonName', () => { it('should resolve packages with metadata (absolute path)', () => { expect(resolveAddonName('@storybook/addon-knobs')).toEqual({ - name: '@storybook/addon-knobs/register', - type: 'managerEntries', + name: '@storybook/addon-knobs', + type: 'presets', }); }); @@ -363,7 +369,7 @@ describe('resolveAddonName', () => { }); it('should resolve presets', () => { - expect(resolveAddonName('@storybook/addon-docs/preset')).toEqual({ + expect(resolveAddonName('@storybook/addon-docs')).toEqual({ name: '@storybook/addon-docs/preset', type: 'presets', }); @@ -381,53 +387,87 @@ describe('resolveAddonName', () => { }); }); -describe('splitAddons', () => { - const { splitAddons } = jest.requireActual('./presets'); +describe('loadPreset', () => { + const { loadPreset } = jest.requireActual('./presets'); - it('should split managerEntries that end in register', () => { - const addons = [ - '@storybook/addon-actions/register', - 'storybook-addon-readme/register', - 'addon-foo/register.js', - 'addon-bar/register.ts', - 'addon-baz/register.tsx', - '@storybook/addon-notes/register-panel', - ]; - expect(splitAddons(addons)).toEqual({ - managerEntries: addons, - presets: [], - }); - }); + mockPreset('@storybook/preset-typescript', {}); + mockPreset('@storybook/addon-docs', {}); + mockPreset('@storybook/addon-actions/register', {}); + mockPreset('addon-foo/register.js', {}); + mockPreset('addon-bar/preset.js', {}); + mockPreset('addon-baz/register.js', {}); + mockPreset('@storybook/addon-notes/register-panel', {}); - it('should split preset packages and package entries', () => { - const addons = [ - '@storybook/addon-essentials', - '@storybook/addon-docs/presets', - 'addon-bar/presets.js', - './local-addon-relative/presets', - ]; - expect(splitAddons(addons)).toEqual({ - managerEntries: [], - presets: addons, - }); - }); - - it('should split preset objects', () => { - const addons = [ - { name: '@storybook/addon-essentials' }, - { name: '@storybook/addon-docs/presets', options: { configureJSX: true } }, - ]; - expect(splitAddons(addons)).toEqual({ - managerEntries: [], - presets: addons, - }); - }); - - it('should skip invalid objects', () => { - const addons = [1, true, { foo: 'bar' }]; - expect(splitAddons(addons)).toEqual({ - managerEntries: [], - presets: [], - }); + it('should resolve all addons & presets in correct order', () => { + const loaded = loadPreset({ + type: 'managerEntries', + name: '', + presets: ['@storybook/preset-typescript'], + addons: [ + '@storybook/addon-docs', + '@storybook/addon-actions/register', + 'addon-foo/register.js', + 'addon-bar', + 'addon-baz/register.tsx', + '@storybook/addon-notes/register-panel', + ], + }); + expect(loaded).toEqual([ + { + name: '@storybook/preset-typescript', + options: {}, + preset: {}, + }, + { + name: '@storybook/addon-actions/register_additionalManagerEntries', + options: {}, + preset: { + managerEntries: ['@storybook/addon-actions/register'], + }, + }, + { + name: 'addon-foo/register.js_additionalManagerEntries', + options: {}, + preset: { + managerEntries: ['addon-foo/register.js'], + }, + }, + // { + // name: 'addon-bar', + // options: {}, + // preset: {}, + // }, + { + name: 'addon-baz/register.tsx_additionalManagerEntries', + options: {}, + preset: { + managerEntries: ['addon-baz/register.tsx'], + }, + }, + { + name: '@storybook/addon-notes/register-panel_additionalManagerEntries', + options: {}, + preset: { + managerEntries: ['@storybook/addon-notes/register-panel'], + }, + }, + { + name: { + presets: ['@storybook/preset-typescript'], + addons: [ + '@storybook/addon-docs', + '@storybook/addon-actions/register', + 'addon-foo/register.js', + 'addon-bar', + 'addon-baz/register.tsx', + '@storybook/addon-notes/register-panel', + ], + name: '', + type: 'managerEntries', + }, + options: {}, + preset: {}, + }, + ]); }); }); From 61b986e8c7103faece5c83f6d99aea48534621bb Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 16 Jun 2020 11:40:09 +0200 Subject: [PATCH 4/6] ADD comment --- lib/core/src/server/presets.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/core/src/server/presets.test.js b/lib/core/src/server/presets.test.js index 23c5ee24c97a..33e1ff0f89f4 100644 --- a/lib/core/src/server/presets.test.js +++ b/lib/core/src/server/presets.test.js @@ -432,6 +432,7 @@ describe('loadPreset', () => { managerEntries: ['addon-foo/register.js'], }, }, + // should be there, but some file mocking problem is causing it to not resolve // { // name: 'addon-bar', // options: {}, From 2f7adfd13671e222afa4630e42647754c0aef276 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 16 Jun 2020 12:36:24 +0200 Subject: [PATCH 5/6] REVERT main.ts change for official storybook --- examples/official-storybook/main.ts | 50 +++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/examples/official-storybook/main.ts b/examples/official-storybook/main.ts index ce7134b34955..c5ebd19e352c 100644 --- a/examples/official-storybook/main.ts +++ b/examples/official-storybook/main.ts @@ -27,4 +27,54 @@ module.exports = { '@storybook/addon-queryparams', ], logLevel: 'debug', + webpackFinal: async (config, { configType }) => ({ + ...config, + module: { + ...config.module, + rules: [ + ...config.module.rules.slice(1), + { + test: /\.(mjs|jsx?|tsx?)$/, + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: `.cache/storybook`, + presets: [ + [ + '@babel/preset-env', + { shippedProposals: true, useBuiltIns: 'usage', corejs: 3 }, + ], + '@babel/preset-typescript', + configType === 'PRODUCTION' && [ + 'babel-preset-minify', + { builtIns: false, mangle: false }, + ], + '@babel/preset-react', + '@babel/preset-flow', + ].filter(Boolean), + plugins: [ + '@babel/plugin-proposal-object-rest-spread', + '@babel/plugin-proposal-class-properties', + '@babel/plugin-syntax-dynamic-import', + ['babel-plugin-emotion', { sourceMap: true, autoLabel: true }], + 'babel-plugin-macros', + 'babel-plugin-add-react-displayname', + [ + 'babel-plugin-react-docgen', + { DOC_GEN_COLLECTION_NAME: 'STORYBOOK_REACT_CLASSES' }, + ], + ], + }, + }, + ], + exclude: [/node_modules/, /dist/], + }, + ], + }, + resolve: { + ...config.resolve, + extensions: [...(config.resolve.extensions || []), '.ts', '.tsx'], + }, + }), } as StorybookConfig; From 7c7d37edbd217bea8fb2fd536da76dc7aa5cd579 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 16 Jun 2020 12:37:57 +0200 Subject: [PATCH 6/6] CLEANUP --- lib/core/src/server/presets.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/core/src/server/presets.js b/lib/core/src/server/presets.js index 2836d85d2505..36e8cce27a34 100644 --- a/lib/core/src/server/presets.js +++ b/lib/core/src/server/presets.js @@ -120,7 +120,6 @@ export const map = (item) => { function interopRequireDefault(filePath) { // eslint-disable-next-line global-require,import/no-dynamic-require const result = require(filePath); - // console.log(filePath, result); const isES6DefaultExported = typeof result === 'object' && result !== null && typeof result.default !== 'undefined';