Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Pass default webpack config as third argument in Full Control Mode #2796

Merged
merged 2 commits into from
Jan 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions app/angular/src/server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import fs from 'fs';
import path from 'path';
import { logger } from '@storybook/node-logger';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import loadBabelConfig from './babel_config';
import loadTsConfig from './ts_config';
import {
Expand Down Expand Up @@ -47,22 +48,28 @@ export default function(configType, baseConfig, configDir) {
logger.info('=> Loading angular-cli config.');
}

const defaultConfig = applyAngularCliWebpackConfig(
createDefaultWebpackConfig(config),
cliWebpackConfigOptions
);

// Check whether user has a custom webpack config file and
// return the (extended) base configuration if it's not available.
const customConfigPath = path.resolve(configDir, 'webpack.config.js');

if (!fs.existsSync(customConfigPath)) {
logger.info('=> Using default webpack setup based on "angular-cli".');
const configPath = path.resolve(__dirname, './config/defaults/webpack.config.js');
const customConfig = require(configPath);

return applyAngularCliWebpackConfig(customConfig(config), cliWebpackConfigOptions);
return defaultConfig;
}
const customConfig = require(customConfigPath);

if (typeof customConfig === 'function') {
logger.info('=> Loading custom webpack config (full-control mode).');
return customConfig(applyAngularCliWebpackConfig(config, cliWebpackConfigOptions), configType);
return customConfig(
applyAngularCliWebpackConfig(config, cliWebpackConfigOptions),
configType,
defaultConfig
Copy link
Member

Choose a reason for hiding this comment

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

So in case of full control mode, there is a first parameter that is extended with angular-cli's config, and the default config which is extended as well. Is this expected?

Copy link
Member Author

@Hypnosphi Hypnosphi Jan 21, 2018

Choose a reason for hiding this comment

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

Given that you actually pick one or another, yes

);
}
logger.info('=> Loading custom webpack config (extending mode).');

Expand Down
8 changes: 5 additions & 3 deletions app/angular/src/server/config/defaults/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import deprecate from 'util-deprecate';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import { includePaths } from '../utils';

module.exports = storybookBaseConfig =>
createDefaultWebpackConfig(storybookBaseConfig, includePaths);
module.exports = deprecate(
createDefaultWebpackConfig,
"importing default webpack config generator from '@storybook/angular/dist/server/config/defaults/webpack.config.js' is deprecated. Use third argument of your exported function instead. See https://storybook.js.org/configurations/custom-webpack-config/#full-control-mode--default"
);
10 changes: 5 additions & 5 deletions app/polymer/src/server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from 'fs';
import path from 'path';
import findCacheDir from 'find-cache-dir';
import { logger } from '@storybook/node-logger';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import loadBabelConfig from './babel_config';

// `baseConfig` is a webpack configuration bundled with storybook.
Expand Down Expand Up @@ -41,22 +42,21 @@ export default function(configType, baseConfig, configDir) {
config.entry.manager.splice(1, 0, storybookDefaultAddonsPath);
}

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 customConfigPath = path.resolve(configDir, 'webpack.config.js');

if (!fs.existsSync(customConfigPath)) {
logger.info('=> Using default webpack setup based on "polymer-cli".');
const configPath = path.resolve(__dirname, './config/defaults/webpack.config.js');
const customConfig = require(configPath);

return customConfig(config);
return defaultConfig;
}
const customConfig = require(customConfigPath);

if (typeof customConfig === 'function') {
logger.info('=> Loading custom webpack config (full-control mode).');
return customConfig(config, configType);
return customConfig(config, configType, defaultConfig);
}
logger.info('=> Loading custom webpack config (extending mode).');
return {
Expand Down
8 changes: 5 additions & 3 deletions app/polymer/src/server/config/defaults/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import deprecate from 'util-deprecate';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import { includePaths } from '../utils';

module.exports = storybookBaseConfig =>
createDefaultWebpackConfig(storybookBaseConfig, includePaths);
module.exports = deprecate(
createDefaultWebpackConfig,
"importing default webpack config generator from '@storybook/polymer/dist/server/config/defaults/webpack.config.js' is deprecated. Use third argument of your exported function instead. See https://storybook.js.org/configurations/custom-webpack-config/#full-control-mode--default"
);
17 changes: 10 additions & 7 deletions app/react-native/src/server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import fs from 'fs';
import path from 'path';
import JSON5 from 'json5';
import findCacheDir from 'find-cache-dir';
import { createDefaultWebpackConfig } from '@storybook/core/server';

// avoid ESLint errors
const logger = console;
Expand Down Expand Up @@ -80,13 +81,13 @@ export default function(configType, baseConfig, projectDir, configDir) {
? path.resolve(babelConfigDir, babelConfig.extends)
: path.resolve(babelConfig.extends);
}
config.module.loaders[0].query = babelConfig;
config.module.rules[0].query = babelConfig;
}

// 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.
config.module.loaders[0].query.cacheDirectory = findCacheDir({
config.module.rules[0].query.cacheDirectory = findCacheDir({
name: 'react-storybook',
});

Expand All @@ -101,19 +102,21 @@ export default function(configType, baseConfig, projectDir, configDir) {
config.entry.manager.unshift(storybookDefaultAddonsPath);
}

const defaultConfig = createDefaultWebpackConfig(config);

// Check whether user has a custom webpack config file and
// return the (extended) base configuration if it's not available.
let customConfigPath = path.resolve(configDir, 'webpack.config.js');
const customConfigPath = path.resolve(configDir, 'webpack.config.js');
if (!fs.existsSync(customConfigPath)) {
logger.info('=> Using default webpack setup based on "Create React App".');
customConfigPath = path.resolve(__dirname, './config/defaults/webpack.config.js');
return defaultConfig;
}

const customConfig = require(customConfigPath); // eslint-disable-line

if (typeof customConfig === 'function') {
logger.info('=> Loading custom webpack config (full-control mode).');
return customConfig(config, configType);
return customConfig(config, configType, defaultConfig);
}

logger.info('=> Loading custom webpack config.');
Expand All @@ -129,9 +132,9 @@ export default function(configType, baseConfig, projectDir, configDir) {
plugins: [...config.plugins, ...(customConfig.plugins || [])],
module: {
...config.module,
// We need to use our and custom loaders.
// We need to use our and custom rules.
...customConfig.module,
loaders: [...config.module.loaders, ...(customConfig.module.loaders || [])],
rules: [...config.module.rules, ...(customConfig.module.rules || [])],
},
};
}
68 changes: 6 additions & 62 deletions app/react-native/src/server/config/defaults/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,7 @@
import autoprefixer from 'autoprefixer';
Copy link
Member

Choose a reason for hiding this comment

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

When I checked this config before, it was a bit different from the default config of the other apps. Are those differences minor? For example, is it safe to change "loaders" to "rules"?

Copy link
Member Author

Choose a reason for hiding this comment

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

loaders field is deprecated in webpack. Technically, it's a breaking change, but I can't really imagine why would someone use a custom webpack config in RN storybook. It doesn't apply to stories themselves anyway.

Generally, the differences are there because changes to configs in react and vue weren't applied here

Copy link
Member

Choose a reason for hiding this comment

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

I guess we need to factor our the RN manager config into @storybook/core too. Maybe given the above it is easier than you thought @igor-dv?

import { includePaths } from '../utils';
import deprecate from 'util-deprecate';
import { createDefaultWebpackConfig } from '@storybook/core/server';

// Add a default custom config which is similar to what React Create App does.
module.exports = storybookBaseConfig => {
const newConfig = { ...storybookBaseConfig };

newConfig.module.loaders = [
...newConfig.module.loaders,
{
test: /\.css?$/,
include: includePaths,
use: [
require.resolve('style-loader'),
require.resolve('css-loader'),
{
loader: require.resolve('postcss-loader'),
options: {
plugins: () => [
autoprefixer({
browsers: ['>1%', 'last 4 versions', 'Firefox ESR', 'not ie < 9'],
}),
],
},
},
],
},
{
test: /\.json$/,
include: includePaths,
loader: require.resolve('json-loader'),
},
{
test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/,
include: includePaths,
loader: require.resolve('file-loader'),
query: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
{
test: /\.(mp4|webm)(\?.*)?$/,
include: includePaths,
loader: require.resolve('url-loader'),
query: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
];

newConfig.resolve = {
...newConfig.resolve,
alias: {
...((newConfig.resolve && newConfig.resolve.alias) || {}),
// This is to support NPM2
'babel-runtime/regenerator': require.resolve('babel-runtime/regenerator'),
},
};

// Return the altered config
return newConfig;
};
module.exports = deprecate(
createDefaultWebpackConfig,
"importing default webpack config generator from '@storybook/react-native/dist/server/config/defaults/webpack.config.js' is deprecated. Use third argument of your exported function instead. See https://storybook.js.org/configurations/custom-webpack-config/#full-control-mode--default"
);
2 changes: 1 addition & 1 deletion app/react-native/src/server/config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const getConfig = options => ({
new CaseSensitivePathsPlugin(),
],
module: {
loaders: [
rules: [
{
test: /\.jsx?$/,
loader: require.resolve('babel-loader'),
Expand Down
2 changes: 1 addition & 1 deletion app/react-native/src/server/config/webpack.config.prod.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const getConfig = options => {
}),
],
module: {
loaders: [
rules: [
{
test: /\.jsx?$/,
loader: require.resolve('babel-loader'),
Expand Down
10 changes: 5 additions & 5 deletions app/react/src/server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import fs from 'fs';
import path from 'path';
import findCacheDir from 'find-cache-dir';
import { logger } from '@storybook/node-logger';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import loadBabelConfig from './babel_config';

// `baseConfig` is a webpack configuration bundled with storybook.
Expand Down Expand Up @@ -41,22 +42,21 @@ export default function(configType, baseConfig, configDir) {
config.entry.manager.splice(1, 0, storybookDefaultAddonsPath);
}

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 customConfigPath = path.resolve(configDir, 'webpack.config.js');

if (!fs.existsSync(customConfigPath)) {
logger.info('=> Using default webpack setup based on "Create React App".');
const configPath = path.resolve(__dirname, './config/defaults/webpack.config.js');
const customConfig = require(configPath);

return customConfig(config);
return defaultConfig;
}
const customConfig = require(customConfigPath);

if (typeof customConfig === 'function') {
logger.info('=> Loading custom webpack config (full-control mode).');
return customConfig(config, configType);
return customConfig(config, configType, defaultConfig);
}
logger.info('=> Loading custom webpack config (extending mode).');
return {
Expand Down
8 changes: 5 additions & 3 deletions app/react/src/server/config/defaults/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import deprecate from 'util-deprecate';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import { includePaths } from '../utils';

module.exports = storybookBaseConfig =>
createDefaultWebpackConfig(storybookBaseConfig, includePaths);
module.exports = deprecate(
createDefaultWebpackConfig,
"importing default webpack config generator from '@storybook/react/dist/server/config/defaults/webpack.config.js' is deprecated. Use third argument of your exported function instead. See https://storybook.js.org/configurations/custom-webpack-config/#full-control-mode--default"
);
10 changes: 5 additions & 5 deletions app/vue/src/server/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import fs from 'fs';
import path from 'path';
import findCacheDir from 'find-cache-dir';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import loadBabelConfig from './babel_config';

// avoid ESLint errors
Expand Down Expand Up @@ -43,22 +44,21 @@ export default function(configType, baseConfig, configDir) {
config.entry.manager.splice(1, 0, storybookDefaultAddonsPath);
}

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 customConfigPath = path.resolve(configDir, 'webpack.config.js');

if (!fs.existsSync(customConfigPath)) {
logger.info('=> Using default webpack setup based on "vue-cli".');
const configPath = path.resolve(__dirname, './config/defaults/webpack.config.js');
const customConfig = require(configPath);

return customConfig(config);
return defaultConfig;
}
const customConfig = require(customConfigPath);

if (typeof customConfig === 'function') {
logger.info('=> Loading custom webpack config (full-control mode).');
return customConfig(config, configType);
return customConfig(config, configType, defaultConfig);
}
logger.info('=> Loading custom webpack config (extending mode).');
return {
Expand Down
8 changes: 5 additions & 3 deletions app/vue/src/server/config/defaults/webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import deprecate from 'util-deprecate';
import { createDefaultWebpackConfig } from '@storybook/core/server';
import { includePaths } from '../utils';

module.exports = storybookBaseConfig =>
createDefaultWebpackConfig(storybookBaseConfig, includePaths);
module.exports = deprecate(
createDefaultWebpackConfig,
"importing default webpack config generator from '@storybook/vue/dist/server/config/defaults/webpack.config.js' is deprecated. Use third argument of your exported function instead. See https://storybook.js.org/configurations/custom-webpack-config/#full-control-mode--default"
);
17 changes: 5 additions & 12 deletions docs/src/pages/configurations/custom-webpack-config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,28 +95,21 @@ You may want to keep Storybook's [default config](/configurations/default-config
If so, this is how you do it using the Full Control Mode.
Add following content to the `webpack.config.js` in your Storybook config directory.

> We plan to expose our default webpack-config as it's own package in the future.

```js
const path = require('path');

// load the default config generator.
const genDefaultConfig = require('@storybook/react/dist/server/config/defaults/webpack.config.js');
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't it be mentioned in docs as a deprecated feature?

Copy link
Member Author

Choose a reason for hiding this comment

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

Why should it?

Copy link
Member

Choose a reason for hiding this comment

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

IDK, just have seen people leave deprecated features with some "deprecated" labels on them... But it's not critical to me 👍

Copy link
Member

Choose a reason for hiding this comment

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

I think if we don't want people to do something we delete it from the docs :)

Unless it's something that we think a lot of people are already doing, in which case a deprecated note could help in some cases. But probably people who are already doing something are unlikely to come back to the docs, so really I don't think it gains much.


module.exports = (baseConfig, env) => {
const config = genDefaultConfig(baseConfig, env);

// Extend it as you need.
module.exports = (baseConfig, env, defaultConfig) => {
// Extend defaultConfig as you need.

// For example, add typescript loader:
config.module.rules.push({
defaultConfig.module.rules.push({
test: /\.(ts|tsx)$/,
include: path.resolve(__dirname, '../src'),
loader: require.resolve('ts-loader')
});
config.resolve.extensions.push('.ts', '.tsx');
defaultConfig.resolve.extensions.push('.ts', '.tsx');

return config;
return defaultConfig;
};
```

Expand Down
Loading