From 77cd59af0349fa142e113d43f40686871327877e Mon Sep 17 00:00:00 2001 From: igor-dv Date: Sun, 19 Aug 2018 16:01:23 +0300 Subject: [PATCH 01/13] Initial implementation of the core and framework presets --- .../server/framework-preset-angular-cli.js | 21 +++++ .../src/server/framework-preset-angular.js | 44 +++++++++++ app/angular/src/server/options.js | 22 +----- app/angular/src/server/wrapInitialConfig.js | 38 --------- ...tialConfig.js => framework-preset-html.js} | 6 +- app/html/src/server/options.js | 4 +- ...ialConfig.js => framework-preset-marko.js} | 6 +- app/marko/src/server/options.js | 4 +- ...lConfig.js => framework-preset-polymer.js} | 6 +- app/polymer/src/server/options.js | 4 +- .../src/server/framework-preset-react.js | 9 +++ app/react/src/server/options.js | 3 +- ...alConfig.js => framework-preset-svelte.js} | 6 +- app/svelte/src/server/options.js | 4 +- ...itialConfig.js => framework-preset-vue.js} | 6 +- app/vue/src/server/options.js | 4 +- lib/core/src/server/build-static.js | 5 +- lib/core/src/server/config.js | 78 +++++++++++-------- lib/core/src/server/core-preset-dev.js | 16 ++++ lib/core/src/server/core-preset-prod.js | 16 ++++ lib/core/src/server/loadCustomBabelConfig.js | 4 +- lib/core/src/server/middleware.js | 3 +- lib/core/src/server/presets.js | 38 +++++---- 23 files changed, 213 insertions(+), 134 deletions(-) create mode 100644 app/angular/src/server/framework-preset-angular-cli.js create mode 100644 app/angular/src/server/framework-preset-angular.js delete mode 100644 app/angular/src/server/wrapInitialConfig.js rename app/html/src/server/{wrapInitialConfig.js => framework-preset-html.js} (77%) rename app/marko/src/server/{wrapInitialConfig.js => framework-preset-marko.js} (80%) rename app/polymer/src/server/{wrapInitialConfig.js => framework-preset-polymer.js} (82%) create mode 100644 app/react/src/server/framework-preset-react.js rename app/svelte/src/server/{wrapInitialConfig.js => framework-preset-svelte.js} (83%) rename app/vue/src/server/{wrapInitialConfig.js => framework-preset-vue.js} (87%) create mode 100644 lib/core/src/server/core-preset-dev.js create mode 100644 lib/core/src/server/core-preset-prod.js diff --git a/app/angular/src/server/framework-preset-angular-cli.js b/app/angular/src/server/framework-preset-angular-cli.js new file mode 100644 index 000000000000..d5010dfade69 --- /dev/null +++ b/app/angular/src/server/framework-preset-angular-cli.js @@ -0,0 +1,21 @@ +import { logger } from '@storybook/node-logger'; + +import { + getAngularCliWebpackConfigOptions, + applyAngularCliWebpackConfig, +} from './angular-cli_config'; + +function extendWebpack(config) { + const cwd = process.cwd(); + const cliWebpackConfigOptions = getAngularCliWebpackConfigOptions(cwd); + + if (cliWebpackConfigOptions) { + logger.info('=> Loading angular-cli config.'); + } + + return applyAngularCliWebpackConfig(config, cliWebpackConfigOptions); +} + +export default { + extendWebpack, +}; diff --git a/app/angular/src/server/framework-preset-angular.js b/app/angular/src/server/framework-preset-angular.js new file mode 100644 index 000000000000..c806825f6eb5 --- /dev/null +++ b/app/angular/src/server/framework-preset-angular.js @@ -0,0 +1,44 @@ +import loadTsConfig from './ts_config'; + +function extendWebpack(config, { configDir }) { + return { + ...config, + module: { + ...config.module, + rules: [ + ...config.module.rules, + { + test: /\.tsx?$/, + use: [ + { + loader: require.resolve('ts-loader'), + options: loadTsConfig(configDir), + }, + require.resolve('angular2-template-loader'), + ], + }, + { + test: /[/\\]@angular[/\\]core[/\\].+\.js$/, + parser: { system: true }, + }, + { + test: /\.html$/, + loader: 'raw-loader', + exclude: /\.async\.html$/, + }, + { + test: /\.scss$/, + use: [require.resolve('raw-loader'), require.resolve('sass-loader')], + }, + ], + }, + resolve: { + ...config.resolve, + extensions: [...config.resolve.extensions, '.ts', '.tsx'], + }, + }; +} + +export default { + extendWebpack, +}; diff --git a/app/angular/src/server/options.js b/app/angular/src/server/options.js index 3029c1dd6ab1..189c31521e3e 100644 --- a/app/angular/src/server/options.js +++ b/app/angular/src/server/options.js @@ -1,24 +1,10 @@ -import { logger } from '@storybook/node-logger'; - import packageJson from '../../package.json'; -import wrapInitialConfig from './wrapInitialConfig'; - -import { - getAngularCliWebpackConfigOptions, - applyAngularCliWebpackConfig, -} from './angular-cli_config'; - -const cliWebpackConfigOptions = getAngularCliWebpackConfigOptions(process.cwd()); - -if (cliWebpackConfigOptions) { - logger.info('=> Loading angular-cli config.'); -} - export default { packageJson, defaultConfigName: 'angular-cli', - wrapInitialConfig, - wrapDefaultConfig: config => applyAngularCliWebpackConfig(config, cliWebpackConfigOptions), - wrapBasicConfig: config => applyAngularCliWebpackConfig(config, cliWebpackConfigOptions), + frameworkPresets: [ + require.resolve('./framework-preset-angular.js'), + require.resolve('./framework-preset-angular-cli.js'), + ], }; diff --git a/app/angular/src/server/wrapInitialConfig.js b/app/angular/src/server/wrapInitialConfig.js deleted file mode 100644 index 9e3314bde478..000000000000 --- a/app/angular/src/server/wrapInitialConfig.js +++ /dev/null @@ -1,38 +0,0 @@ -import loadTsConfig from './ts_config'; - -export default (config, configDir) => ({ - ...config, - module: { - ...config.module, - rules: [ - ...config.module.rules, - { - test: /\.tsx?$/, - use: [ - { - loader: require.resolve('ts-loader'), - options: loadTsConfig(configDir), - }, - require.resolve('angular2-template-loader'), - ], - }, - { - test: /[/\\]@angular[/\\]core[/\\].+\.js$/, - parser: { system: true }, - }, - { - test: /\.html$/, - loader: 'raw-loader', - exclude: /\.async\.html$/, - }, - { - test: /\.scss$/, - use: [require.resolve('raw-loader'), require.resolve('sass-loader')], - }, - ], - }, - resolve: { - ...config.resolve, - extensions: [...config.resolve.extensions, '.ts', '.tsx'], - }, -}); diff --git a/app/html/src/server/wrapInitialConfig.js b/app/html/src/server/framework-preset-html.js similarity index 77% rename from app/html/src/server/wrapInitialConfig.js rename to app/html/src/server/framework-preset-html.js index 5e5cae9cda29..abcd2cb51b8e 100644 --- a/app/html/src/server/wrapInitialConfig.js +++ b/app/html/src/server/framework-preset-html.js @@ -1,4 +1,4 @@ -export default config => ({ +const extendWebpack = config => ({ ...config, module: { ...config.module, @@ -15,3 +15,7 @@ export default config => ({ ], }, }); + +export default { + extendWebpack, +}; diff --git a/app/html/src/server/options.js b/app/html/src/server/options.js index 94465235684e..03953efd592f 100644 --- a/app/html/src/server/options.js +++ b/app/html/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapInitialConfig from './wrapInitialConfig'; - export default { packageJson, - wrapInitialConfig, + frameworkPresets: [require.resolve('./framework-preset-html.js')], }; diff --git a/app/marko/src/server/wrapInitialConfig.js b/app/marko/src/server/framework-preset-marko.js similarity index 80% rename from app/marko/src/server/wrapInitialConfig.js rename to app/marko/src/server/framework-preset-marko.js index 1f75a15da8dd..447adc78ece5 100644 --- a/app/marko/src/server/wrapInitialConfig.js +++ b/app/marko/src/server/framework-preset-marko.js @@ -1,4 +1,4 @@ -export default config => ({ +const extendWebpack = config => ({ ...config, module: { ...config.module, @@ -15,3 +15,7 @@ export default config => ({ extensions: [...config.resolve.extensions, '.marko'], }, }); + +export default { + extendWebpack, +}; diff --git a/app/marko/src/server/options.js b/app/marko/src/server/options.js index 94465235684e..00159044ab48 100644 --- a/app/marko/src/server/options.js +++ b/app/marko/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapInitialConfig from './wrapInitialConfig'; - export default { packageJson, - wrapInitialConfig, + frameworkPresets: [require.resolve('./framework-preset-marko.js')], }; diff --git a/app/polymer/src/server/wrapInitialConfig.js b/app/polymer/src/server/framework-preset-polymer.js similarity index 82% rename from app/polymer/src/server/wrapInitialConfig.js rename to app/polymer/src/server/framework-preset-polymer.js index 4e8ae233c8a0..22f5469aebd3 100644 --- a/app/polymer/src/server/wrapInitialConfig.js +++ b/app/polymer/src/server/framework-preset-polymer.js @@ -1,4 +1,4 @@ -export default config => ({ +const extendWebpack = config => ({ ...config, module: { ...config.module, @@ -17,3 +17,7 @@ export default config => ({ ], }, }); + +export default { + extendWebpack, +}; diff --git a/app/polymer/src/server/options.js b/app/polymer/src/server/options.js index 94465235684e..81879f131cd7 100644 --- a/app/polymer/src/server/options.js +++ b/app/polymer/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapInitialConfig from './wrapInitialConfig'; - export default { packageJson, - wrapInitialConfig, + frameworkPresets: [require.resolve('./framework-preset-polymer.js')], }; diff --git a/app/react/src/server/framework-preset-react.js b/app/react/src/server/framework-preset-react.js new file mode 100644 index 000000000000..9f271e94e520 --- /dev/null +++ b/app/react/src/server/framework-preset-react.js @@ -0,0 +1,9 @@ +import wrapBabelConfig from './wrapBabelConfig'; + +function extendBabel(config) { + return wrapBabelConfig(config); +} + +export default { + extendBabel, +}; diff --git a/app/react/src/server/options.js b/app/react/src/server/options.js index 4a1f528b8e65..5d7ed0c15538 100644 --- a/app/react/src/server/options.js +++ b/app/react/src/server/options.js @@ -1,11 +1,10 @@ import packageJson from '../../package.json'; -import wrapBabelConfig from './wrapBabelConfig'; import wrapDefaultBabelConfig from './wrapDefaultBabelConfig'; export default { packageJson, defaultConfigName: 'create-react-app', + frameworkPresets: [require.resolve('./framework-preset-react.js')], wrapDefaultBabelConfig, - wrapBabelConfig, }; diff --git a/app/svelte/src/server/wrapInitialConfig.js b/app/svelte/src/server/framework-preset-svelte.js similarity index 83% rename from app/svelte/src/server/wrapInitialConfig.js rename to app/svelte/src/server/framework-preset-svelte.js index 46a2b89aa117..68141c257e69 100644 --- a/app/svelte/src/server/wrapInitialConfig.js +++ b/app/svelte/src/server/framework-preset-svelte.js @@ -1,4 +1,4 @@ -export default config => ({ +const extendWebpack = config => ({ ...config, module: { ...config.module, @@ -17,3 +17,7 @@ export default config => ({ alias: config.resolve.alias, }, }); + +export default { + extendWebpack, +}; diff --git a/app/svelte/src/server/options.js b/app/svelte/src/server/options.js index 94465235684e..3e4a77d76407 100644 --- a/app/svelte/src/server/options.js +++ b/app/svelte/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapInitialConfig from './wrapInitialConfig'; - export default { packageJson, - wrapInitialConfig, + frameworkPresets: [require.resolve('./framework-preset-svelte.js')], }; diff --git a/app/vue/src/server/wrapInitialConfig.js b/app/vue/src/server/framework-preset-vue.js similarity index 87% rename from app/vue/src/server/wrapInitialConfig.js rename to app/vue/src/server/framework-preset-vue.js index b4b66c8e49d3..34b02d8210d5 100644 --- a/app/vue/src/server/wrapInitialConfig.js +++ b/app/vue/src/server/framework-preset-vue.js @@ -1,6 +1,6 @@ const VueLoaderPlugin = require('vue-loader/lib/plugin'); -export default config => ({ +const extendWebpack = config => ({ ...config, plugins: [...config.plugins, new VueLoaderPlugin()], module: { @@ -23,3 +23,7 @@ export default config => ({ }, }, }); + +export default { + extendWebpack, +}; diff --git a/app/vue/src/server/options.js b/app/vue/src/server/options.js index 94465235684e..f23034d439df 100644 --- a/app/vue/src/server/options.js +++ b/app/vue/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapInitialConfig from './wrapInitialConfig'; - export default { packageJson, - wrapInitialConfig, + frameworkPresets: [require.resolve('./framework-preset-vue.js')], }; diff --git a/lib/core/src/server/build-static.js b/lib/core/src/server/build-static.js index 80fdd23fbd91..21a0071e7dbb 100644 --- a/lib/core/src/server/build-static.js +++ b/lib/core/src/server/build-static.js @@ -7,8 +7,6 @@ import shelljs from 'shelljs'; import { logger } from '@storybook/node-logger'; import { parseList, getEnvConfig } from './utils'; import './config/env'; -import getBaseConfig from './config/webpack.config.prod'; -import defaultBabelConfig from './config/babel.prod'; import loadConfig from './config'; const defaultFavIcon = require.resolve('./public/favicon.ico'); @@ -48,9 +46,8 @@ export function buildStatic({ packageJson, ...loadOptions }) { // NOTE changes to env should be done before calling `getBaseConfig` const config = loadConfig({ configType: 'PRODUCTION', - getBaseConfig, + corePresets: [require.resolve('./core-preset-prod.js')], configDir, - defaultBabelConfig, ...loadOptions, }); config.output.path = path.resolve(outputDir); diff --git a/lib/core/src/server/config.js b/lib/core/src/server/config.js index 0eb115a578a2..d0812a68f3cd 100644 --- a/lib/core/src/server/config.js +++ b/lib/core/src/server/config.js @@ -1,11 +1,11 @@ +import path from 'path'; import findCacheDir from 'find-cache-dir'; import { logger } from '@storybook/node-logger'; import { createDefaultWebpackConfig } from './config/defaults/webpack.config'; -import devBabelConfig from './config/babel'; -import loadCustomBabelConfig from './loadCustomBabelConfig'; import loadCustomWebpackConfig from './loadCustomWebpackConfig'; import loadPresets from './presets'; import mergeConfigs from './mergeConfigs'; +import serverRequire from './serverRequire'; const noopWrapper = config => config; @@ -18,43 +18,38 @@ function informAboutCustomConfig(defaultConfigName) { logger.info(`=> Using default webpack setup based on "${defaultConfigName}".`); } -function getBabelConfig(options, presets) { - const { - configDir, - defaultBabelConfig = devBabelConfig, - wrapDefaultBabelConfig = noopWrapper, - wrapBabelConfig = noopWrapper, - } = options; +function customPreset({ configDir }) { + const presets = serverRequire(path.resolve(configDir, 'presets')); + return loadPresets(presets); +} + +function getBabelConfig(options, corePresets, frameworkPresets, customPresets) { + const { configDir, wrapDefaultBabelConfig = noopWrapper } = options; - const defaultConfig = wrapDefaultBabelConfig(defaultBabelConfig); - const customBabelConfig = loadCustomBabelConfig(configDir, defaultConfig); - const frameworkBabelConfig = wrapBabelConfig(customBabelConfig); - const presetBabelConfig = presets.extendBabel(frameworkBabelConfig); + const coreBabelConfig = corePresets.extendBabel({}, { configDir, wrapDefaultBabelConfig }); + const frameworkBabelConfig = frameworkPresets.extendBabel(coreBabelConfig); + const babelConfig = customPresets.extendBabel(frameworkBabelConfig); return { // This is a feature of `babel-loader` for webpack (not Babel itself). // It enables a cache directory for faster-rebuilds // `find-cache-dir` will create the cache directory under the node_modules directory. cacheDirectory: findCacheDir({ name: 'react-storybook' }), - ...presetBabelConfig, + ...babelConfig, }; } -function getWebpackConfig(options, babelOptions, presets) { - const { - configType, - getBaseConfig, - configDir, - defaultConfigName, - wrapInitialConfig = noopWrapper, - wrapBasicConfig = noopWrapper, - wrapDefaultConfig = noopWrapper, - } = options; - - const baseConfig = getBaseConfig({ ...options, babelOptions, presets }); - const initialConfig = wrapInitialConfig(baseConfig, configDir); - const config = presets.extendWebpack(initialConfig); - const defaultConfig = wrapDefaultConfig(createDefaultWebpackConfig(config)); +function getWebpackConfig(options, babelOptions, corePresets, frameworkPresets, customPresets) { + const { configType, configDir, defaultConfigName } = options; + + const coreConfig = corePresets.extendWebpack( + {}, + { ...options, babelOptions, presets: customPresets } + ); // core presets + const frameworkConfig = frameworkPresets.extendWebpack(coreConfig, { configDir }); // framework presets + const config = customPresets.extendWebpack(frameworkConfig); // custom presets + + const defaultConfig = createDefaultWebpackConfig(config); // Check whether user has a custom webpack config file and // return the (extended) base configuration if it's not available. @@ -67,7 +62,7 @@ function getWebpackConfig(options, babelOptions, presets) { if (typeof customConfig === 'function') { logger.info('=> Loading custom webpack config (full-control mode).'); - return customConfig(wrapBasicConfig(config), configType, defaultConfig); + return customConfig(config, configType, defaultConfig); } logger.info('=> Loading custom webpack config (extending mode).'); @@ -76,9 +71,24 @@ function getWebpackConfig(options, babelOptions, presets) { } export default options => { - const { configDir } = options; + const { corePresets, frameworkPresets, ...restOptions } = options; + + const loadedCorePresets = loadPresets(corePresets); + const loadedFrameworkPresets = loadPresets(frameworkPresets); + const loadedCustomPresets = customPreset(options); + + const babelOptions = getBabelConfig( + restOptions, + loadedCorePresets, + loadedFrameworkPresets, + loadedCustomPresets + ); - const presets = loadPresets(configDir); - const babelOptions = getBabelConfig(options, presets); - return getWebpackConfig(options, babelOptions, presets); + return getWebpackConfig( + restOptions, + babelOptions, + loadedCorePresets, + loadedFrameworkPresets, + loadedCustomPresets + ); }; diff --git a/lib/core/src/server/core-preset-dev.js b/lib/core/src/server/core-preset-dev.js new file mode 100644 index 000000000000..ed5f2dd8b7cd --- /dev/null +++ b/lib/core/src/server/core-preset-dev.js @@ -0,0 +1,16 @@ +import loadCustomBabelConfig from './loadCustomBabelConfig'; +import createDevConfig from './config/webpack.config'; +import defaultBabelConfig from './config/babel'; + +function extendWebpack(_, options) { + return createDevConfig(options); +} + +function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { + return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); +} + +export default { + extendWebpack, + extendBabel, +}; diff --git a/lib/core/src/server/core-preset-prod.js b/lib/core/src/server/core-preset-prod.js new file mode 100644 index 000000000000..29f40f0129b2 --- /dev/null +++ b/lib/core/src/server/core-preset-prod.js @@ -0,0 +1,16 @@ +import loadCustomBabelConfig from './loadCustomBabelConfig'; +import createProdConfig from './config/webpack.config.prod'; +import defaultBabelConfig from './config/babel.prod'; + +function extendWebpack(_, options) { + return createProdConfig(options); +} + +function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { + return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); +} + +export default { + extendWebpack, + extendBabel, +}; diff --git a/lib/core/src/server/loadCustomBabelConfig.js b/lib/core/src/server/loadCustomBabelConfig.js index 8180f9b9d792..7a796846b5a7 100644 --- a/lib/core/src/server/loadCustomBabelConfig.js +++ b/lib/core/src/server/loadCustomBabelConfig.js @@ -43,7 +43,7 @@ function loadFromPath(babelConfigPath) { return config; } -export default function(configDir, defaultConfig) { +export default function(configDir) { let babelConfig = loadFromPath(path.resolve(configDir, '.babelrc')); let inConfigDir = true; @@ -62,5 +62,5 @@ export default function(configDir, defaultConfig) { } } - return babelConfig || defaultConfig; + return babelConfig; } diff --git a/lib/core/src/server/middleware.js b/lib/core/src/server/middleware.js index 3b541075e940..e35f0398ae69 100644 --- a/lib/core/src/server/middleware.js +++ b/lib/core/src/server/middleware.js @@ -3,7 +3,6 @@ import { Router } from 'express'; import webpack from 'webpack'; import webpackDevMiddleware from 'webpack-dev-middleware'; import webpackHotMiddleware from 'webpack-hot-middleware'; -import getBaseConfig from './config/webpack.config'; import { getMiddleware } from './utils'; import loadConfig from './config'; @@ -20,7 +19,7 @@ export default function(configDir, loadOptions, quiet) { // custom `.babelrc` file and `webpack.config.js` files const config = loadConfig({ configType: 'DEVELOPMENT', - getBaseConfig, + corePresets: [require.resolve('./core-preset-dev.js')], configDir, quiet, ...loadOptions, diff --git a/lib/core/src/server/presets.js b/lib/core/src/server/presets.js index 003fa8320c8b..48d489e11521 100644 --- a/lib/core/src/server/presets.js +++ b/lib/core/src/server/presets.js @@ -1,13 +1,20 @@ -import path from 'path'; import { logger } from '@storybook/node-logger'; -import serverRequire from './serverRequire'; + +function interopRequireDefault(filePath) { + // eslint-disable-next-line global-require,import/no-dynamic-require + const result = require(filePath); + + const isES6DefaultExported = + typeof result === 'object' && result !== null && typeof result.default !== 'undefined'; + + return isES6DefaultExported ? result.default : result; +} function loadPreset(preset) { try { if (typeof preset === 'string') { return { - // eslint-disable-next-line global-require,import/no-dynamic-require - preset: require(preset), + preset: interopRequireDefault(preset), options: {}, }; } @@ -15,8 +22,7 @@ function loadPreset(preset) { const { name, options } = preset; return { - // eslint-disable-next-line global-require,import/no-dynamic-require - preset: require(name), + preset: interopRequireDefault(name), options, }; } catch (e) { @@ -35,7 +41,7 @@ function loadPresets(presets) { return presets.map(loadPreset).filter(preset => preset); } -function applyPresets(presets, config, extension) { +function applyPresets(presets, config, args = {}, extension) { if (!presets.length) { return config; } @@ -44,22 +50,26 @@ function applyPresets(presets, config, extension) { const extensionFn = preset[extension]; if (extensionFn && typeof extensionFn === 'function') { - return extensionFn.call(preset, accumulatedConfig, options); + const combinedOptions = { + ...args, + ...options, + }; + + return extensionFn.call(preset, accumulatedConfig, combinedOptions); } return accumulatedConfig; }, config); } -function getPresets(configDir) { - const presets = serverRequire(path.resolve(configDir, 'presets')); +function getPresets(presets) { const loadedPresets = loadPresets(presets); return { - extendBabel: config => applyPresets(loadedPresets, config, 'extendBabel'), - extendWebpack: config => applyPresets(loadedPresets, config, 'extendWebpack'), - extendPreview: config => applyPresets(loadedPresets, config, 'extendPreview'), - extendManager: config => applyPresets(loadedPresets, config, 'extendManager'), + extendBabel: (config, args) => applyPresets(loadedPresets, config, args, 'extendBabel'), + extendWebpack: (config, args) => applyPresets(loadedPresets, config, args, 'extendWebpack'), + extendPreview: (config, args) => applyPresets(loadedPresets, config, args, 'extendPreview'), + extendManager: (config, args) => applyPresets(loadedPresets, config, args, 'extendManager'), }; } From a64cdf40ac4d7b566057443c09f9af5fa9d51a9e Mon Sep 17 00:00:00 2001 From: igor-dv Date: Sun, 19 Aug 2018 16:46:21 +0300 Subject: [PATCH 02/13] Fix presets.test.js --- lib/core/src/server/presets.test.js | 42 ++++++++--------------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/lib/core/src/server/presets.test.js b/lib/core/src/server/presets.test.js index afea645b8340..9887ef8b4189 100644 --- a/lib/core/src/server/presets.test.js +++ b/lib/core/src/server/presets.test.js @@ -1,20 +1,14 @@ -function mockPresetsFile(mockPresets) { - jest.mock('./serverRequire.js', () => () => mockPresets); -} - function mockPreset(name, mockPresetObject) { jest.mock(name, () => mockPresetObject, { virtual: true }); } describe('presets', () => { it('does not throw when there is no preset file', () => { - mockPresetsFile(); - const loadPresets = require.requireActual('./presets').default; let presets; expect(() => { - presets = loadPresets(__dirname); + presets = loadPresets(); presets.extendWebpack(); presets.extendBabel(); presets.extendPreview(); @@ -25,10 +19,8 @@ describe('presets', () => { }); it('does not throw when presets are empty', () => { - mockPresetsFile([]); - const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets([]); expect(() => { presets.extendWebpack(); @@ -39,10 +31,8 @@ describe('presets', () => { }); it('does not throw when preset can not be loaded', () => { - mockPresetsFile(['preset-foo']); - const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets(['preset-foo']); expect(() => { presets.extendWebpack({}); @@ -53,8 +43,6 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as a string', () => { - mockPresetsFile(['preset-foo', 'preset-bar']); - const mockPresetFooExtendWebpack = jest.fn(); const mockPresetBarExtendBabel = jest.fn(); @@ -67,7 +55,7 @@ describe('presets', () => { }); const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets(['preset-foo', 'preset-bar']); expect(() => { presets.extendWebpack(); @@ -81,8 +69,6 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as an object without props', () => { - mockPresetsFile([{ name: 'preset-foo' }, { name: 'preset-bar' }]); - const mockPresetFooExtendWebpack = jest.fn(); const mockPresetBarExtendBabel = jest.fn(); @@ -95,7 +81,7 @@ describe('presets', () => { }); const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets([{ name: 'preset-foo' }, { name: 'preset-bar' }]); expect(() => { presets.extendWebpack(); @@ -109,11 +95,6 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as an object with props', () => { - mockPresetsFile([ - { name: 'preset-foo', options: { foo: 1 } }, - { name: 'preset-bar', options: { bar: 'a' } }, - ]); - const mockPresetFooExtendWebpack = jest.fn(); const mockPresetBarExtendBabel = jest.fn(); @@ -126,7 +107,10 @@ describe('presets', () => { }); const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets([ + { name: 'preset-foo', options: { foo: 1 } }, + { name: 'preset-bar', options: { bar: 'a' } }, + ]); expect(() => { presets.extendWebpack({}); @@ -140,8 +124,6 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as a string and as an object', () => { - mockPresetsFile(['preset-foo', { name: 'preset-bar', options: { bar: 'a' } }]); - const mockPresetFooExtendWebpack = jest.fn(); const mockPresetBarExtendBabel = jest.fn(); @@ -154,7 +136,7 @@ describe('presets', () => { }); const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets(['preset-foo', { name: 'preset-bar', options: { bar: 'a' } }]); expect(() => { presets.extendWebpack({}); @@ -168,8 +150,6 @@ describe('presets', () => { }); it('applies presets in chain', () => { - mockPresetsFile(['preset-foo', { name: 'preset-bar', options: { bar: 'a' } }]); - const mockPresetFooExtendWebpack = jest.fn(() => ({})); const mockPresetBarExtendWebpack = jest.fn(() => ({})); @@ -182,7 +162,7 @@ describe('presets', () => { }); const loadPresets = require.requireActual('./presets').default; - const presets = loadPresets(__dirname); + const presets = loadPresets(['preset-foo', { name: 'preset-bar', options: { bar: 'a' } }]); expect(() => { presets.extendWebpack({}); From 60176a537a733129293650017dace019cd79a0c2 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Sun, 19 Aug 2018 16:47:15 +0300 Subject: [PATCH 03/13] Combine all presets to one and add core-preset-babel-cache and core-preset-webpack-custom --- lib/core/src/server/config.js | 89 ++++--------------- .../src/server/core-preset-babel-cache.js | 15 ++++ .../src/server/core-preset-webpack-custom.js | 39 ++++++++ 3 files changed, 69 insertions(+), 74 deletions(-) create mode 100644 lib/core/src/server/core-preset-babel-cache.js create mode 100644 lib/core/src/server/core-preset-webpack-custom.js diff --git a/lib/core/src/server/config.js b/lib/core/src/server/config.js index d0812a68f3cd..955e12dc2b1a 100644 --- a/lib/core/src/server/config.js +++ b/lib/core/src/server/config.js @@ -1,94 +1,35 @@ import path from 'path'; -import findCacheDir from 'find-cache-dir'; -import { logger } from '@storybook/node-logger'; -import { createDefaultWebpackConfig } from './config/defaults/webpack.config'; -import loadCustomWebpackConfig from './loadCustomWebpackConfig'; import loadPresets from './presets'; -import mergeConfigs from './mergeConfigs'; import serverRequire from './serverRequire'; const noopWrapper = config => config; -function informAboutCustomConfig(defaultConfigName) { - if (!defaultConfigName) { - logger.info('=> Using default webpack setup.'); - return; - } - - logger.info(`=> Using default webpack setup based on "${defaultConfigName}".`); -} - function customPreset({ configDir }) { - const presets = serverRequire(path.resolve(configDir, 'presets')); - return loadPresets(presets); + return serverRequire(path.resolve(configDir, 'presets')) || []; } -function getBabelConfig(options, corePresets, frameworkPresets, customPresets) { +function getBabelConfig(options, presets) { const { configDir, wrapDefaultBabelConfig = noopWrapper } = options; - - const coreBabelConfig = corePresets.extendBabel({}, { configDir, wrapDefaultBabelConfig }); - const frameworkBabelConfig = frameworkPresets.extendBabel(coreBabelConfig); - const babelConfig = customPresets.extendBabel(frameworkBabelConfig); - - return { - // This is a feature of `babel-loader` for webpack (not Babel itself). - // It enables a cache directory for faster-rebuilds - // `find-cache-dir` will create the cache directory under the node_modules directory. - cacheDirectory: findCacheDir({ name: 'react-storybook' }), - ...babelConfig, - }; + return presets.extendBabel({}, { configDir, wrapDefaultBabelConfig }); } -function getWebpackConfig(options, babelOptions, corePresets, frameworkPresets, customPresets) { - const { configType, configDir, defaultConfigName } = options; - - const coreConfig = corePresets.extendWebpack( - {}, - { ...options, babelOptions, presets: customPresets } - ); // core presets - const frameworkConfig = frameworkPresets.extendWebpack(coreConfig, { configDir }); // framework presets - const config = customPresets.extendWebpack(frameworkConfig); // custom presets - - const defaultConfig = createDefaultWebpackConfig(config); - - // Check whether user has a custom webpack config file and - // return the (extended) base configuration if it's not available. - const customConfig = loadCustomWebpackConfig(configDir); - - if (customConfig === null) { - informAboutCustomConfig(defaultConfigName); - return defaultConfig; - } - - if (typeof customConfig === 'function') { - logger.info('=> Loading custom webpack config (full-control mode).'); - return customConfig(config, configType, defaultConfig); - } - - logger.info('=> Loading custom webpack config (extending mode).'); - - return mergeConfigs(config, customConfig); +function getWebpackConfig(options, presets) { + const babelOptions = getBabelConfig(options, presets); + return presets.extendWebpack({}, { ...options, babelOptions, presets }); } export default options => { const { corePresets, frameworkPresets, ...restOptions } = options; - const loadedCorePresets = loadPresets(corePresets); - const loadedFrameworkPresets = loadPresets(frameworkPresets); - const loadedCustomPresets = customPreset(options); + const presetsConfig = [ + ...corePresets, + require.resolve('./core-preset-babel-cache.js'), + ...frameworkPresets, + ...customPreset(options), + require.resolve('./core-preset-webpack-custom.js'), + ]; - const babelOptions = getBabelConfig( - restOptions, - loadedCorePresets, - loadedFrameworkPresets, - loadedCustomPresets - ); + const presets = loadPresets(presetsConfig); - return getWebpackConfig( - restOptions, - babelOptions, - loadedCorePresets, - loadedFrameworkPresets, - loadedCustomPresets - ); + return getWebpackConfig(restOptions, presets); }; diff --git a/lib/core/src/server/core-preset-babel-cache.js b/lib/core/src/server/core-preset-babel-cache.js new file mode 100644 index 000000000000..12b160dbed9c --- /dev/null +++ b/lib/core/src/server/core-preset-babel-cache.js @@ -0,0 +1,15 @@ +import findCacheDir from 'find-cache-dir'; + +function extendBabel(babelConfig) { + return { + // This is a feature of `babel-loader` for webpack (not Babel itself). + // It enables a cache directory for faster-rebuilds + // `find-cache-dir` will create the cache directory under the node_modules directory. + cacheDirectory: findCacheDir({ name: 'react-storybook' }), + ...babelConfig, + }; +} + +export default { + extendBabel, +}; diff --git a/lib/core/src/server/core-preset-webpack-custom.js b/lib/core/src/server/core-preset-webpack-custom.js new file mode 100644 index 000000000000..9c2899f4a24c --- /dev/null +++ b/lib/core/src/server/core-preset-webpack-custom.js @@ -0,0 +1,39 @@ +import { logger } from '@storybook/node-logger'; +import loadCustomWebpackConfig from './loadCustomWebpackConfig'; +import mergeConfigs from './mergeConfigs'; +import { createDefaultWebpackConfig } from './config/defaults/webpack.config'; + +function informAboutCustomConfig(defaultConfigName) { + if (!defaultConfigName) { + logger.info('=> Using default webpack setup.'); + return; + } + + logger.info(`=> Using default webpack setup based on "${defaultConfigName}".`); +} + +function extendWebpack(config, { configDir, configType, defaultConfigName }) { + const defaultConfig = createDefaultWebpackConfig(config); + + // Check whether user has a custom webpack config file and + // return the (extended) base configuration if it's not available. + const customConfig = loadCustomWebpackConfig(configDir); + + if (customConfig === null) { + informAboutCustomConfig(defaultConfigName); + return defaultConfig; + } + + if (typeof customConfig === 'function') { + logger.info('=> Loading custom webpack config (full-control mode).'); + return customConfig(config, configType, defaultConfig); + } + + logger.info('=> Loading custom webpack config (extending mode).'); + + return mergeConfigs(config, customConfig); +} + +export default { + extendWebpack, +}; From d08fac0b1c76b2c9b6b0a73f359615d3acfef934 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Sun, 19 Aug 2018 17:16:17 +0300 Subject: [PATCH 04/13] Build "entries" with presets and inject them to the presets.extendWebpack --- lib/core/src/server/config.js | 15 +++++++++------ lib/core/src/server/config/entries.js | 14 ++++++++------ lib/core/src/server/config/webpack.config.js | 13 ++----------- lib/core/src/server/config/webpack.config.prod.js | 5 +---- lib/core/src/server/core-preset-dev.js | 14 ++++++++++++++ lib/core/src/server/core-preset-prod.js | 11 +++++++++++ 6 files changed, 45 insertions(+), 27 deletions(-) diff --git a/lib/core/src/server/config.js b/lib/core/src/server/config.js index 955e12dc2b1a..9beb8e858ddb 100644 --- a/lib/core/src/server/config.js +++ b/lib/core/src/server/config.js @@ -8,14 +8,17 @@ function customPreset({ configDir }) { return serverRequire(path.resolve(configDir, 'presets')) || []; } -function getBabelConfig(options, presets) { +function getWebpackConfig(options, presets) { const { configDir, wrapDefaultBabelConfig = noopWrapper } = options; - return presets.extendBabel({}, { configDir, wrapDefaultBabelConfig }); -} -function getWebpackConfig(options, presets) { - const babelOptions = getBabelConfig(options, presets); - return presets.extendWebpack({}, { ...options, babelOptions, presets }); + const babelOptions = presets.extendBabel({}, { configDir, wrapDefaultBabelConfig }); + + const entries = { + iframe: presets.extendPreview([], options), + manager: presets.extendManager([], options), + }; + + return presets.extendWebpack({}, { ...options, babelOptions, entries }); } export default options => { diff --git a/lib/core/src/server/config/entries.js b/lib/core/src/server/config/entries.js index 9faca130b348..f0c461c846a1 100644 --- a/lib/core/src/server/config/entries.js +++ b/lib/core/src/server/config/entries.js @@ -2,9 +2,8 @@ import path from 'path'; import { logger } from '@storybook/node-logger'; import { getInterpretedFile } from './interpret-files'; -export default function getEntries(configDir, presets) { +export function createPreviewEntry({ configDir }) { const iframe = [require.resolve('./polyfills'), require.resolve('./globals')]; - const manager = [require.resolve('./polyfills'), require.resolve('../../client/manager')]; // Check whether a config.{ext} file exists inside the storybook // config directory and throw an error if it's not. @@ -15,6 +14,12 @@ export default function getEntries(configDir, presets) { iframe.push(require.resolve(storybookConfigPath)); + return iframe; +} + +export function createManagerEntry({ configDir }) { + const manager = [require.resolve('./polyfills'), require.resolve('../../client/manager')]; + // Check whether addons.{ext} file exists inside the storybook. const storybookCustomAddonsPath = getInterpretedFile(path.resolve(configDir, 'addons')); if (storybookCustomAddonsPath) { @@ -22,8 +27,5 @@ export default function getEntries(configDir, presets) { manager.unshift(storybookCustomAddonsPath); } - return { - iframe: presets.extendPreview(iframe), - manager: presets.extendManager(manager), - }; + return manager; } diff --git a/lib/core/src/server/config/webpack.config.js b/lib/core/src/server/config/webpack.config.js index 0f19f9f61d1c..9ac685f39c34 100644 --- a/lib/core/src/server/config/webpack.config.js +++ b/lib/core/src/server/config/webpack.config.js @@ -5,14 +5,11 @@ import Dotenv from 'dotenv-webpack'; import WatchMissingNodeModulesPlugin from 'react-dev-utils/WatchMissingNodeModulesPlugin'; import CaseSensitivePathsPlugin from 'case-sensitive-paths-webpack-plugin'; import GeneratePagePlugin from 'generate-page-webpack-plugin'; -import getEntries from './entries'; import { includePaths, excludePaths, nodeModulesPaths, loadEnv, nodePaths } from './utils'; import { getPreviewHeadHtml, getManagerHeadHtml, getPreviewBodyHtml } from '../utils'; import { version } from '../../../package.json'; -export default ({ configDir, quiet, babelOptions, presets }) => { - const entries = getEntries(configDir, presets); - +export default ({ configDir, quiet, babelOptions, entries }) => { const entriesMeta = { iframe: { headHtmlSnippet: getPreviewHeadHtml(configDir, process.env), @@ -26,13 +23,7 @@ export default ({ configDir, quiet, babelOptions, presets }) => { return { mode: 'development', devtool: 'cheap-module-source-map', - entry: { - ...entries, - iframe: [ - ...entries.iframe, - `${require.resolve('webpack-hot-middleware/client')}?reload=true`, - ], - }, + entry: entries, output: { path: path.join(__dirname, 'dist'), filename: 'static/[name].bundle.js', diff --git a/lib/core/src/server/config/webpack.config.prod.js b/lib/core/src/server/config/webpack.config.prod.js index 3ef01c40039c..8edd6a072ebd 100644 --- a/lib/core/src/server/config/webpack.config.prod.js +++ b/lib/core/src/server/config/webpack.config.prod.js @@ -2,14 +2,11 @@ import webpack from 'webpack'; import { getEnvironment } from 'universal-dotenv'; import Dotenv from 'dotenv-webpack'; import GeneratePagePlugin from 'generate-page-webpack-plugin'; -import getEntries from './entries'; import { version } from '../../../package.json'; import { includePaths, excludePaths, loadEnv, nodePaths } from './utils'; import { getPreviewHeadHtml, getManagerHeadHtml, getPreviewBodyHtml } from '../utils'; -export default ({ configDir, babelOptions, presets }) => { - const entries = getEntries(configDir, presets); - +export default ({ configDir, babelOptions, entries }) => { const entriesMeta = { iframe: { headHtmlSnippet: getPreviewHeadHtml(configDir, process.env), diff --git a/lib/core/src/server/core-preset-dev.js b/lib/core/src/server/core-preset-dev.js index ed5f2dd8b7cd..46907c9cdf04 100644 --- a/lib/core/src/server/core-preset-dev.js +++ b/lib/core/src/server/core-preset-dev.js @@ -1,6 +1,7 @@ import loadCustomBabelConfig from './loadCustomBabelConfig'; import createDevConfig from './config/webpack.config'; import defaultBabelConfig from './config/babel'; +import { createManagerEntry, createPreviewEntry } from './config/entries'; function extendWebpack(_, options) { return createDevConfig(options); @@ -10,7 +11,20 @@ function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); } +function extendManager(_, options) { + return createManagerEntry(options); +} + +function extendPreview(_, options) { + return [ + ...createPreviewEntry(options), + `${require.resolve('webpack-hot-middleware/client')}?reload=true`, + ]; +} + export default { extendWebpack, extendBabel, + extendManager, + extendPreview, }; diff --git a/lib/core/src/server/core-preset-prod.js b/lib/core/src/server/core-preset-prod.js index 29f40f0129b2..afcfcfa11aa5 100644 --- a/lib/core/src/server/core-preset-prod.js +++ b/lib/core/src/server/core-preset-prod.js @@ -1,6 +1,7 @@ import loadCustomBabelConfig from './loadCustomBabelConfig'; import createProdConfig from './config/webpack.config.prod'; import defaultBabelConfig from './config/babel.prod'; +import { createManagerEntry, createPreviewEntry } from './config/entries'; function extendWebpack(_, options) { return createProdConfig(options); @@ -10,7 +11,17 @@ function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); } +function extendManager(_, options) { + return createManagerEntry(options); +} + +function extendPreview(_, options) { + return createPreviewEntry(options); +} + export default { extendWebpack, extendBabel, + extendManager, + extendPreview, }; From 06d5178ead56cd40a5b39d952a6998790208297b Mon Sep 17 00:00:00 2001 From: igor-dv Date: Sun, 19 Aug 2018 17:30:32 +0300 Subject: [PATCH 05/13] Logging presets with "=>" --- lib/core/src/server/presets.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/src/server/presets.js b/lib/core/src/server/presets.js index 48d489e11521..7b9acb1df4ea 100644 --- a/lib/core/src/server/presets.js +++ b/lib/core/src/server/presets.js @@ -36,7 +36,7 @@ function loadPresets(presets) { return []; } - logger.info('Loading presets'); + logger.info('=> Loading presets'); return presets.map(loadPreset).filter(preset => preset); } From fdb41b9bad81f1717e2c6de670481df891c87606 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Sun, 19 Aug 2018 19:55:44 +0300 Subject: [PATCH 06/13] Set empty array as a default for the corePresets and frameworkPresets --- lib/core/src/server/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/src/server/config.js b/lib/core/src/server/config.js index 9beb8e858ddb..77ad36af69c7 100644 --- a/lib/core/src/server/config.js +++ b/lib/core/src/server/config.js @@ -22,7 +22,7 @@ function getWebpackConfig(options, presets) { } export default options => { - const { corePresets, frameworkPresets, ...restOptions } = options; + const { corePresets = [], frameworkPresets = [], ...restOptions } = options; const presetsConfig = [ ...corePresets, From 2ef180d4886bee84b3203445fc3cdc0bcde47812 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Fri, 24 Aug 2018 01:43:26 +0300 Subject: [PATCH 07/13] Naming --- lib/core/server.js | 2 +- lib/core/src/server/config/{babel.js => babel.dev.js} | 0 lib/core/src/server/config/babel.prod.js | 2 +- lib/core/src/server/config/entries.js | 2 +- .../webpack.config.js => webpack.config.default.js} | 0 .../config/{webpack.config.js => webpack.config.dev.js} | 0 lib/core/src/server/core-preset-dev.js | 8 ++++---- lib/core/src/server/core-preset-webpack-custom.js | 2 +- lib/core/src/server/{config => }/interpret-files.js | 0 lib/core/src/server/{config => }/interpret-files.test.js | 0 lib/core/src/server/serverRequire.js | 2 +- 11 files changed, 9 insertions(+), 9 deletions(-) rename lib/core/src/server/config/{babel.js => babel.dev.js} (100%) rename lib/core/src/server/config/{defaults/webpack.config.js => webpack.config.default.js} (100%) rename lib/core/src/server/config/{webpack.config.js => webpack.config.dev.js} (100%) rename lib/core/src/server/{config => }/interpret-files.js (100%) rename lib/core/src/server/{config => }/interpret-files.test.js (100%) diff --git a/lib/core/server.js b/lib/core/server.js index 0bb731d2e702..fa6e79114ae5 100644 --- a/lib/core/server.js +++ b/lib/core/server.js @@ -1,4 +1,4 @@ -const defaultWebpackConfig = require('./dist/server/config/defaults/webpack.config'); +const defaultWebpackConfig = require('./dist/server/config/webpack.config.default'); const serverUtils = require('./dist/server/utils'); const buildStatic = require('./dist/server/build-static'); const buildDev = require('./dist/server/build-dev'); diff --git a/lib/core/src/server/config/babel.js b/lib/core/src/server/config/babel.dev.js similarity index 100% rename from lib/core/src/server/config/babel.js rename to lib/core/src/server/config/babel.dev.js diff --git a/lib/core/src/server/config/babel.prod.js b/lib/core/src/server/config/babel.prod.js index f3e6efbf5f51..bec1d022793e 100644 --- a/lib/core/src/server/config/babel.prod.js +++ b/lib/core/src/server/config/babel.prod.js @@ -1,4 +1,4 @@ -import baseConfig from './babel'; +import baseConfig from './babel.dev'; export default { ...baseConfig, diff --git a/lib/core/src/server/config/entries.js b/lib/core/src/server/config/entries.js index f0c461c846a1..95dc7f2113f8 100644 --- a/lib/core/src/server/config/entries.js +++ b/lib/core/src/server/config/entries.js @@ -1,6 +1,6 @@ import path from 'path'; import { logger } from '@storybook/node-logger'; -import { getInterpretedFile } from './interpret-files'; +import { getInterpretedFile } from '../interpret-files'; export function createPreviewEntry({ configDir }) { const iframe = [require.resolve('./polyfills'), require.resolve('./globals')]; diff --git a/lib/core/src/server/config/defaults/webpack.config.js b/lib/core/src/server/config/webpack.config.default.js similarity index 100% rename from lib/core/src/server/config/defaults/webpack.config.js rename to lib/core/src/server/config/webpack.config.default.js diff --git a/lib/core/src/server/config/webpack.config.js b/lib/core/src/server/config/webpack.config.dev.js similarity index 100% rename from lib/core/src/server/config/webpack.config.js rename to lib/core/src/server/config/webpack.config.dev.js diff --git a/lib/core/src/server/core-preset-dev.js b/lib/core/src/server/core-preset-dev.js index 46907c9cdf04..1b2f4cf97774 100644 --- a/lib/core/src/server/core-preset-dev.js +++ b/lib/core/src/server/core-preset-dev.js @@ -1,14 +1,14 @@ import loadCustomBabelConfig from './loadCustomBabelConfig'; -import createDevConfig from './config/webpack.config'; -import defaultBabelConfig from './config/babel'; +import createDevConfig from './config/webpack.config.dev'; +import defaultBabelConfig from './config/babel.dev'; import { createManagerEntry, createPreviewEntry } from './config/entries'; function extendWebpack(_, options) { return createDevConfig(options); } -function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { - return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); +function extendBabel(_, { configDir }) { + return loadCustomBabelConfig(configDir) || defaultBabelConfig; } function extendManager(_, options) { diff --git a/lib/core/src/server/core-preset-webpack-custom.js b/lib/core/src/server/core-preset-webpack-custom.js index 9c2899f4a24c..3badf0122de8 100644 --- a/lib/core/src/server/core-preset-webpack-custom.js +++ b/lib/core/src/server/core-preset-webpack-custom.js @@ -1,7 +1,7 @@ import { logger } from '@storybook/node-logger'; import loadCustomWebpackConfig from './loadCustomWebpackConfig'; import mergeConfigs from './mergeConfigs'; -import { createDefaultWebpackConfig } from './config/defaults/webpack.config'; +import { createDefaultWebpackConfig } from './config/webpack.config.default'; function informAboutCustomConfig(defaultConfigName) { if (!defaultConfigName) { diff --git a/lib/core/src/server/config/interpret-files.js b/lib/core/src/server/interpret-files.js similarity index 100% rename from lib/core/src/server/config/interpret-files.js rename to lib/core/src/server/interpret-files.js diff --git a/lib/core/src/server/config/interpret-files.test.js b/lib/core/src/server/interpret-files.test.js similarity index 100% rename from lib/core/src/server/config/interpret-files.test.js rename to lib/core/src/server/interpret-files.test.js diff --git a/lib/core/src/server/serverRequire.js b/lib/core/src/server/serverRequire.js index db47dc4ae2c5..8f48ffc2bd2f 100644 --- a/lib/core/src/server/serverRequire.js +++ b/lib/core/src/server/serverRequire.js @@ -1,6 +1,6 @@ import interpret from 'interpret'; import { logger } from '@storybook/node-logger'; -import { getInterpretedFileWithExt } from './config/interpret-files'; +import { getInterpretedFileWithExt } from './interpret-files'; // The code based on https://github.com/webpack/webpack-cli/blob/ca504de8c7c0ea66278021b72fa6a953e3ffa43c/bin/convert-argv From 1e47756be91832e854b71912d6d5ea54bedf1533 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Fri, 24 Aug 2018 01:57:35 +0300 Subject: [PATCH 08/13] Fix unwanted change --- lib/core/src/server/core-preset-dev.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/src/server/core-preset-dev.js b/lib/core/src/server/core-preset-dev.js index 1b2f4cf97774..0bf5a24fdfa6 100644 --- a/lib/core/src/server/core-preset-dev.js +++ b/lib/core/src/server/core-preset-dev.js @@ -7,8 +7,8 @@ function extendWebpack(_, options) { return createDevConfig(options); } -function extendBabel(_, { configDir }) { - return loadCustomBabelConfig(configDir) || defaultBabelConfig; +function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { + return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); } function extendManager(_, options) { From 846faf4bdd7148507199914f737e952c27560a90 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Fri, 24 Aug 2018 02:02:17 +0300 Subject: [PATCH 09/13] Add storybookDefault to babel default config for the future purpose. --- lib/core/src/server/config/babel.dev.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/src/server/config/babel.dev.js b/lib/core/src/server/config/babel.dev.js index 7beb6d718c9b..ce0c4c57f223 100644 --- a/lib/core/src/server/config/babel.dev.js +++ b/lib/core/src/server/config/babel.dev.js @@ -1,4 +1,6 @@ export default { + // this flag is here to allow presets to recognize the SB default config + storybookDefault: true, // Don't try to find .babelrc because we want to force this configuration. babelrc: false, presets: [ From 6e813efa8ebd0b78a4258f6ef7a20a3784fd8b2e Mon Sep 17 00:00:00 2001 From: igor-dv Date: Fri, 24 Aug 2018 02:26:06 +0300 Subject: [PATCH 10/13] Revert --- lib/core/src/server/config/babel.dev.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/core/src/server/config/babel.dev.js b/lib/core/src/server/config/babel.dev.js index ce0c4c57f223..7beb6d718c9b 100644 --- a/lib/core/src/server/config/babel.dev.js +++ b/lib/core/src/server/config/babel.dev.js @@ -1,6 +1,4 @@ export default { - // this flag is here to allow presets to recognize the SB default config - storybookDefault: true, // Don't try to find .babelrc because we want to force this configuration. babelrc: false, presets: [ From 12426fad9ec010a4caa298ba6a26db69b63eb26d Mon Sep 17 00:00:00 2001 From: igor-dv Date: Fri, 24 Aug 2018 16:27:46 +0300 Subject: [PATCH 11/13] Get rid of wrapDefaultBabelConfig --- .../src/server/framework-preset-mithril.js | 13 +++++ app/mithril/src/server/options.js | 4 +- .../src/server/wrapDefaultBabelConfig.js | 4 -- ...ig.js => framework-preset-react-docgen.js} | 6 +- ... => framework-preset-react-docgen.test.js} | 10 ++-- .../src/server/framework-preset-react.js | 8 ++- app/react/src/server/options.js | 8 +-- .../src/server/wrapDefaultBabelConfig.js | 8 --- app/vue/src/server/framework-preset-vue.js | 56 +++++++++++-------- app/vue/src/server/options.js | 2 - app/vue/src/server/wrapDefaultBabelConfig.js | 4 -- lib/core/src/server/config.js | 6 +- lib/core/src/server/core-preset-dev.js | 4 +- lib/core/src/server/core-preset-prod.js | 4 +- 14 files changed, 73 insertions(+), 64 deletions(-) create mode 100644 app/mithril/src/server/framework-preset-mithril.js delete mode 100644 app/mithril/src/server/wrapDefaultBabelConfig.js rename app/react/src/server/{wrapBabelConfig.js => framework-preset-react-docgen.js} (88%) rename app/react/src/server/{wrapBabelConfig.test.js => framework-preset-react-docgen.test.js} (86%) delete mode 100644 app/react/src/server/wrapDefaultBabelConfig.js delete mode 100644 app/vue/src/server/wrapDefaultBabelConfig.js diff --git a/app/mithril/src/server/framework-preset-mithril.js b/app/mithril/src/server/framework-preset-mithril.js new file mode 100644 index 000000000000..3fb0e3b6b788 --- /dev/null +++ b/app/mithril/src/server/framework-preset-mithril.js @@ -0,0 +1,13 @@ +import { mergeBabel } from '@storybook/core/server'; + +function extendBabel(config) { + const patch = { + plugins: [require.resolve('@babel/plugin-transform-react-jsx')], + }; + + return mergeBabel(patch, config); +} + +export default { + extendBabel, +}; diff --git a/app/mithril/src/server/options.js b/app/mithril/src/server/options.js index db27a1abc311..1f6aa7326e1c 100644 --- a/app/mithril/src/server/options.js +++ b/app/mithril/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapDefaultBabelConfig from './wrapDefaultBabelConfig'; - export default { packageJson, - wrapDefaultBabelConfig, + frameworkPresets: [require.resolve('./framework-preset-mithril.js')], }; diff --git a/app/mithril/src/server/wrapDefaultBabelConfig.js b/app/mithril/src/server/wrapDefaultBabelConfig.js deleted file mode 100644 index 51298e0f9d37..000000000000 --- a/app/mithril/src/server/wrapDefaultBabelConfig.js +++ /dev/null @@ -1,4 +0,0 @@ -export default config => ({ - ...config, - plugins: [...config.plugins, require.resolve('@babel/plugin-transform-react-jsx')], -}); diff --git a/app/react/src/server/wrapBabelConfig.js b/app/react/src/server/framework-preset-react-docgen.js similarity index 88% rename from app/react/src/server/wrapBabelConfig.js rename to app/react/src/server/framework-preset-react-docgen.js index 1f27f6bcc406..235deb1eddf6 100644 --- a/app/react/src/server/wrapBabelConfig.js +++ b/app/react/src/server/framework-preset-react-docgen.js @@ -1,4 +1,4 @@ -export default function(config) { +function extendBabel(config) { // Ensure plugins are defined or fallback to an array to avoid empty values. const babelConfigPlugins = config.plugins || []; @@ -18,3 +18,7 @@ export default function(config) { plugins: [].concat(babelConfigPlugins, extraPlugins), }; } + +export default { + extendBabel, +}; diff --git a/app/react/src/server/wrapBabelConfig.test.js b/app/react/src/server/framework-preset-react-docgen.test.js similarity index 86% rename from app/react/src/server/wrapBabelConfig.test.js rename to app/react/src/server/framework-preset-react-docgen.test.js index 5ad6484583b0..350170e71f56 100644 --- a/app/react/src/server/wrapBabelConfig.test.js +++ b/app/react/src/server/framework-preset-react-docgen.test.js @@ -1,6 +1,6 @@ -import wrapBabelConfig from './wrapBabelConfig'; +import preset from './framework-preset-react-docgen'; -describe('babel_config', () => { +describe('framework-preset-react-docgen', () => { const babelPluginReactDocgenPath = require.resolve('babel-plugin-react-docgen'); it('should return the config with the extra plugins when `plugins` is an array.', () => { @@ -10,7 +10,7 @@ describe('babel_config', () => { plugins: ['foo-plugin'], }; - const config = wrapBabelConfig(babelConfig); + const config = preset.extendBabel(babelConfig); expect(config).toEqual({ babelrc: false, @@ -34,7 +34,7 @@ describe('babel_config', () => { plugins: 'bar-plugin', }; - const config = wrapBabelConfig(babelConfig); + const config = preset.extendBabel(babelConfig); expect(config).toEqual({ babelrc: false, @@ -57,7 +57,7 @@ describe('babel_config', () => { presets: ['env', 'foo-preset'], }; - const config = wrapBabelConfig(babelConfig); + const config = preset.extendBabel(babelConfig); expect(config).toEqual({ babelrc: false, diff --git a/app/react/src/server/framework-preset-react.js b/app/react/src/server/framework-preset-react.js index 9f271e94e520..2e83849eae1f 100644 --- a/app/react/src/server/framework-preset-react.js +++ b/app/react/src/server/framework-preset-react.js @@ -1,7 +1,11 @@ -import wrapBabelConfig from './wrapBabelConfig'; +import { mergeBabel } from '@storybook/core/server'; function extendBabel(config) { - return wrapBabelConfig(config); + const patch = { + presets: [require.resolve('@babel/preset-react'), require.resolve('@babel/preset-flow')], + }; + + return mergeBabel(patch, config); } export default { diff --git a/app/react/src/server/options.js b/app/react/src/server/options.js index 5d7ed0c15538..1dda06fe1e3c 100644 --- a/app/react/src/server/options.js +++ b/app/react/src/server/options.js @@ -1,10 +1,10 @@ import packageJson from '../../package.json'; -import wrapDefaultBabelConfig from './wrapDefaultBabelConfig'; - export default { packageJson, defaultConfigName: 'create-react-app', - frameworkPresets: [require.resolve('./framework-preset-react.js')], - wrapDefaultBabelConfig, + frameworkPresets: [ + require.resolve('./framework-preset-react.js'), + require.resolve('./framework-preset-react-docgen.js'), + ], }; diff --git a/app/react/src/server/wrapDefaultBabelConfig.js b/app/react/src/server/wrapDefaultBabelConfig.js deleted file mode 100644 index 345da14ea06d..000000000000 --- a/app/react/src/server/wrapDefaultBabelConfig.js +++ /dev/null @@ -1,8 +0,0 @@ -export default config => ({ - ...config, - presets: [ - ...config.presets, - require.resolve('@babel/preset-react'), - require.resolve('@babel/preset-flow'), - ], -}); diff --git a/app/vue/src/server/framework-preset-vue.js b/app/vue/src/server/framework-preset-vue.js index 34b02d8210d5..7808c5f60b8d 100644 --- a/app/vue/src/server/framework-preset-vue.js +++ b/app/vue/src/server/framework-preset-vue.js @@ -1,29 +1,41 @@ -const VueLoaderPlugin = require('vue-loader/lib/plugin'); +import VueLoaderPlugin from 'vue-loader/lib/plugin'; +import { mergeBabel } from '@storybook/core/server'; -const extendWebpack = config => ({ - ...config, - plugins: [...config.plugins, new VueLoaderPlugin()], - module: { - ...config.module, - rules: [ - ...config.module.rules, - { - test: /\.vue$/, - loader: require.resolve('vue-loader'), - options: {}, +function extendWebpack(config) { + return { + ...config, + plugins: [...config.plugins, new VueLoaderPlugin()], + module: { + ...config.module, + rules: [ + ...config.module.rules, + { + test: /\.vue$/, + loader: require.resolve('vue-loader'), + options: {}, + }, + ], + }, + resolve: { + ...config.resolve, + extensions: [...config.resolve.extensions, '.vue'], + alias: { + ...config.resolve.alias, + vue$: require.resolve('vue/dist/vue.esm.js'), }, - ], - }, - resolve: { - ...config.resolve, - extensions: [...config.resolve.extensions, '.vue'], - alias: { - ...config.resolve.alias, - vue$: require.resolve('vue/dist/vue.esm.js'), }, - }, -}); + }; +} + +function extendBabel(config) { + const patch = { + presets: [require.resolve('babel-preset-vue')], + }; + + return mergeBabel(patch, config); +} export default { extendWebpack, + extendBabel, }; diff --git a/app/vue/src/server/options.js b/app/vue/src/server/options.js index f80595d4ac41..f23034d439df 100644 --- a/app/vue/src/server/options.js +++ b/app/vue/src/server/options.js @@ -1,8 +1,6 @@ import packageJson from '../../package.json'; -import wrapDefaultBabelConfig from './wrapDefaultBabelConfig'; export default { packageJson, - wrapDefaultBabelConfig, frameworkPresets: [require.resolve('./framework-preset-vue.js')], }; diff --git a/app/vue/src/server/wrapDefaultBabelConfig.js b/app/vue/src/server/wrapDefaultBabelConfig.js deleted file mode 100644 index 0a26326b07ac..000000000000 --- a/app/vue/src/server/wrapDefaultBabelConfig.js +++ /dev/null @@ -1,4 +0,0 @@ -export default config => ({ - ...config, - presets: [...config.presets, require.resolve('babel-preset-vue')], -}); diff --git a/lib/core/src/server/config.js b/lib/core/src/server/config.js index 77ad36af69c7..c3ac32841309 100644 --- a/lib/core/src/server/config.js +++ b/lib/core/src/server/config.js @@ -2,16 +2,12 @@ import path from 'path'; import loadPresets from './presets'; import serverRequire from './serverRequire'; -const noopWrapper = config => config; - function customPreset({ configDir }) { return serverRequire(path.resolve(configDir, 'presets')) || []; } function getWebpackConfig(options, presets) { - const { configDir, wrapDefaultBabelConfig = noopWrapper } = options; - - const babelOptions = presets.extendBabel({}, { configDir, wrapDefaultBabelConfig }); + const babelOptions = presets.extendBabel({}, options); const entries = { iframe: presets.extendPreview([], options), diff --git a/lib/core/src/server/core-preset-dev.js b/lib/core/src/server/core-preset-dev.js index 0bf5a24fdfa6..1b2f4cf97774 100644 --- a/lib/core/src/server/core-preset-dev.js +++ b/lib/core/src/server/core-preset-dev.js @@ -7,8 +7,8 @@ function extendWebpack(_, options) { return createDevConfig(options); } -function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { - return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); +function extendBabel(_, { configDir }) { + return loadCustomBabelConfig(configDir) || defaultBabelConfig; } function extendManager(_, options) { diff --git a/lib/core/src/server/core-preset-prod.js b/lib/core/src/server/core-preset-prod.js index afcfcfa11aa5..73fe88c80ad6 100644 --- a/lib/core/src/server/core-preset-prod.js +++ b/lib/core/src/server/core-preset-prod.js @@ -7,8 +7,8 @@ function extendWebpack(_, options) { return createProdConfig(options); } -function extendBabel(_, { configDir, wrapDefaultBabelConfig }) { - return loadCustomBabelConfig(configDir) || wrapDefaultBabelConfig(defaultBabelConfig); +function extendBabel(_, { configDir }) { + return loadCustomBabelConfig(configDir) || defaultBabelConfig; } function extendManager(_, options) { From 885ad8165d078aab93364141b54a45526b79b585 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Fri, 24 Aug 2018 16:29:34 +0300 Subject: [PATCH 12/13] Add mergeBabel --- lib/core/package.json | 2 + lib/core/server.js | 5 +- lib/core/src/server/babel-core-proxy.js | 10 ++++ lib/core/src/server/mergeBabel.js | 72 +++++++++++++++++++++++++ yarn.lock | 12 ++++- 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 lib/core/src/server/babel-core-proxy.js create mode 100644 lib/core/src/server/mergeBabel.js diff --git a/lib/core/package.json b/lib/core/package.json index 19061ba65ac1..4dcf2c3b076d 100644 --- a/lib/core/package.json +++ b/lib/core/package.json @@ -35,6 +35,7 @@ "commander": "^2.17.0", "core-js": "^2.5.7", "css-loader": "^1.0.0", + "deepmerge": "^2.1.1", "dotenv-webpack": "^1.5.7", "ejs": "^2.6.1", "emotion": "^9.2.6", @@ -45,6 +46,7 @@ "global": "^4.3.2", "interpret": "^1.1.0", "json5": "^1.0.1", + "object.omit": "^3.0.0", "postcss-flexbugs-fixes": "^4.1.0", "postcss-loader": "^2.1.6", "prop-types": "^15.6.2", diff --git a/lib/core/server.js b/lib/core/server.js index fa6e79114ae5..603f09b0e1eb 100644 --- a/lib/core/server.js +++ b/lib/core/server.js @@ -2,5 +2,8 @@ const defaultWebpackConfig = require('./dist/server/config/webpack.config.defaul const serverUtils = require('./dist/server/utils'); const buildStatic = require('./dist/server/build-static'); const buildDev = require('./dist/server/build-dev'); +const mergeBabel = require('./dist/server/mergeBabel'); -module.exports = Object.assign({}, defaultWebpackConfig, buildStatic, buildDev, serverUtils); +module.exports = Object.assign({}, defaultWebpackConfig, buildStatic, buildDev, serverUtils, { + mergeBabel, +}); diff --git a/lib/core/src/server/babel-core-proxy.js b/lib/core/src/server/babel-core-proxy.js new file mode 100644 index 000000000000..32e616947ce1 --- /dev/null +++ b/lib/core/src/server/babel-core-proxy.js @@ -0,0 +1,10 @@ +/* eslint-disable import/no-extraneous-dependencies,global-require */ +let babelCore = null; + +try { + babelCore = require('@babel/core'); +} catch (e) { + babelCore = require('babel-core'); +} + +module.exports = babelCore; diff --git a/lib/core/src/server/mergeBabel.js b/lib/core/src/server/mergeBabel.js new file mode 100644 index 000000000000..3a7b47e4a275 --- /dev/null +++ b/lib/core/src/server/mergeBabel.js @@ -0,0 +1,72 @@ +/* eslint-disable no-param-reassign,no-shadow */ +// based on https://raw.githubusercontent.com/neutrinojs/babel-merge +// we can't use this package because we need to have babel/core as a peer + +import omit from 'object.omit'; +import merge from 'deepmerge'; +import { resolvePlugin, resolvePreset } from './babel-core-proxy'; + +function arrayMerge(source = [], overrides = []) { + return [...new Set([...source, ...overrides])]; +} + +function mergeArray(source = [], overrides = [], resolve, deepmergeOpts) { + return [...source, ...overrides].reduce((reduction, override) => { + const overrideName = resolve(Array.isArray(override) ? override[0] : override); + const overrideOptions = Array.isArray(override) ? override[1] : {}; + + const base = reduction.find(base => { + const baseName = resolve(Array.isArray(base) ? base[0] : base); + return baseName === overrideName || baseName.includes(overrideName); + }); + + const index = reduction.includes(base) ? reduction.indexOf(base) : reduction.length; + const baseName = base ? resolve(Array.isArray(base) ? base[0] : base) : overrideName; + const baseOptions = Array.isArray(base) ? base[1] : {}; + const options = merge(baseOptions, overrideOptions, { + arrayMerge, + isMergeableObject: value => Array.isArray(value), + ...deepmergeOpts, + }); + + reduction[index] = Object.keys(options).length ? [baseName, options] : baseName; + + return reduction; + }, []); +} + +function babelMerge(source = {}, overrides = {}, deepmergeOpts) { + const plugins = mergeArray(source.plugins, overrides.plugins, resolvePlugin, deepmergeOpts); + const presets = mergeArray(source.presets, overrides.presets, resolvePreset, deepmergeOpts); + const sourceEnv = source.env || {}; + const overridesEnv = overrides.env || {}; + + return Object.assign( + presets.length ? { presets } : {}, + plugins.length ? { plugins } : {}, + merge.all( + [ + omit(source, ['plugins', 'presets', 'env']), + omit(overrides, ['plugins', 'presets', 'env']), + ...[...new Set([...Object.keys(sourceEnv), ...Object.keys(overridesEnv)])].map(name => ({ + env: { + [name]: babelMerge(sourceEnv[name], overridesEnv[name], deepmergeOpts), + }, + })), + ], + { arrayMerge, ...deepmergeOpts } + ) + ); +} + +Object.defineProperty(babelMerge, 'all', { + value: (values = [], deepmergeOpts) => + values.reduce((acc, value) => { + if (value) { + Object.assign(acc, babelMerge(acc, value, deepmergeOpts)); + } + return acc; + }, {}), +}); + +module.exports = babelMerge; diff --git a/yarn.lock b/yarn.lock index 5c89e6fc2f4b..1fbd4de51328 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5742,6 +5742,10 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +deepmerge@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.1.1.tgz#e862b4e45ea0555072bf51e7fd0d9845170ae768" + default-require-extensions@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" @@ -9056,7 +9060,7 @@ is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" -is-extendable@^1.0.1: +is-extendable@^1.0.0, is-extendable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" dependencies: @@ -12563,6 +12567,12 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" +object.omit@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-3.0.0.tgz#0e3edc2fce2ba54df5577ff529f6d97bd8a522af" + dependencies: + is-extendable "^1.0.0" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" From 209fe99e4bba21320be75ec247ead70cdaea9137 Mon Sep 17 00:00:00 2001 From: igor-dv Date: Mon, 3 Sep 2018 02:25:18 +0300 Subject: [PATCH 13/13] Fix mergeBabel --- lib/core/src/server/mergeBabel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/src/server/mergeBabel.js b/lib/core/src/server/mergeBabel.js index 3a7b47e4a275..72ddf62c79d8 100644 --- a/lib/core/src/server/mergeBabel.js +++ b/lib/core/src/server/mergeBabel.js @@ -1,5 +1,5 @@ /* eslint-disable no-param-reassign,no-shadow */ -// based on https://raw.githubusercontent.com/neutrinojs/babel-merge +// https://github.com/neutrinojs/babel-merge // we can't use this package because we need to have babel/core as a peer import omit from 'object.omit'; @@ -13,7 +13,7 @@ function arrayMerge(source = [], overrides = []) { function mergeArray(source = [], overrides = [], resolve, deepmergeOpts) { return [...source, ...overrides].reduce((reduction, override) => { const overrideName = resolve(Array.isArray(override) ? override[0] : override); - const overrideOptions = Array.isArray(override) ? override[1] : {}; + const overrideOptions = Array.isArray(override) ? override[1] || {} : {}; const base = reduction.find(base => { const baseName = resolve(Array.isArray(base) ? base[0] : base);