Initial implementation of the core and framework presets

This commit is contained in:
igor-dv 2018-08-19 16:01:23 +03:00
parent f258617a4c
commit 77cd59af03
23 changed files with 212 additions and 133 deletions

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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'),
],
};

View File

@ -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'],
},
});

View File

@ -1,4 +1,4 @@
export default config => ({
const extendWebpack = config => ({
...config,
module: {
...config.module,
@ -15,3 +15,7 @@ export default config => ({
],
},
});
export default {
extendWebpack,
};

View File

@ -1,8 +1,6 @@
import packageJson from '../../package.json';
import wrapInitialConfig from './wrapInitialConfig';
export default {
packageJson,
wrapInitialConfig,
frameworkPresets: [require.resolve('./framework-preset-html.js')],
};

View File

@ -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,
};

View File

@ -1,8 +1,6 @@
import packageJson from '../../package.json';
import wrapInitialConfig from './wrapInitialConfig';
export default {
packageJson,
wrapInitialConfig,
frameworkPresets: [require.resolve('./framework-preset-marko.js')],
};

View File

@ -1,4 +1,4 @@
export default config => ({
const extendWebpack = config => ({
...config,
module: {
...config.module,
@ -17,3 +17,7 @@ export default config => ({
],
},
});
export default {
extendWebpack,
};

View File

@ -1,8 +1,6 @@
import packageJson from '../../package.json';
import wrapInitialConfig from './wrapInitialConfig';
export default {
packageJson,
wrapInitialConfig,
frameworkPresets: [require.resolve('./framework-preset-polymer.js')],
};

View File

@ -0,0 +1,9 @@
import wrapBabelConfig from './wrapBabelConfig';
function extendBabel(config) {
return wrapBabelConfig(config);
}
export default {
extendBabel,
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -1,8 +1,6 @@
import packageJson from '../../package.json';
import wrapInitialConfig from './wrapInitialConfig';
export default {
packageJson,
wrapInitialConfig,
frameworkPresets: [require.resolve('./framework-preset-svelte.js')],
};

View File

@ -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,
};

View File

@ -1,8 +1,6 @@
import packageJson from '../../package.json';
import wrapInitialConfig from './wrapInitialConfig';
export default {
packageJson,
wrapInitialConfig,
frameworkPresets: [require.resolve('./framework-preset-vue.js')],
};

View File

@ -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);

View File

@ -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);
}
const defaultConfig = wrapDefaultBabelConfig(defaultBabelConfig);
const customBabelConfig = loadCustomBabelConfig(configDir, defaultConfig);
const frameworkBabelConfig = wrapBabelConfig(customBabelConfig);
const presetBabelConfig = presets.extendBabel(frameworkBabelConfig);
function getBabelConfig(options, corePresets, frameworkPresets, customPresets) {
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' }),
...presetBabelConfig,
...babelConfig,
};
}
function getWebpackConfig(options, babelOptions, presets) {
const {
configType,
getBaseConfig,
configDir,
defaultConfigName,
wrapInitialConfig = noopWrapper,
wrapBasicConfig = noopWrapper,
wrapDefaultConfig = noopWrapper,
} = options;
function getWebpackConfig(options, babelOptions, corePresets, frameworkPresets, customPresets) {
const { configType, configDir, defaultConfigName } = options;
const baseConfig = getBaseConfig({ ...options, babelOptions, presets });
const initialConfig = wrapInitialConfig(baseConfig, configDir);
const config = presets.extendWebpack(initialConfig);
const defaultConfig = wrapDefaultConfig(createDefaultWebpackConfig(config));
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 presets = loadPresets(configDir);
const babelOptions = getBabelConfig(options, presets);
return getWebpackConfig(options, babelOptions, presets);
const loadedCorePresets = loadPresets(corePresets);
const loadedFrameworkPresets = loadPresets(frameworkPresets);
const loadedCustomPresets = customPreset(options);
const babelOptions = getBabelConfig(
restOptions,
loadedCorePresets,
loadedFrameworkPresets,
loadedCustomPresets
);
return getWebpackConfig(
restOptions,
babelOptions,
loadedCorePresets,
loadedFrameworkPresets,
loadedCustomPresets
);
};

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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;
}

View File

@ -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,

View File

@ -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'),
};
}