-
-
Notifications
You must be signed in to change notification settings - Fork 10k
Expand file tree
/
Copy pathconfig.js
More file actions
143 lines (123 loc) · 4.48 KB
/
config.js
File metadata and controls
143 lines (123 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* eslint global-require: 0 */
import fs from 'fs';
import path from 'path';
import JSON5 from 'json5';
// avoid ESLint errors
const logger = console;
function removeReactHmre(presets) {
const index = presets.indexOf('react-hmre');
if (index > -1) {
presets.splice(index, 1);
}
}
// Tries to load a .babelrc and returns the parsed object if successful
function loadBabelConfig(babelConfigPath) {
let config;
if (fs.existsSync(babelConfigPath)) {
const content = fs.readFileSync(babelConfigPath, 'utf-8');
try {
config = JSON5.parse(content);
config.babelrc = false;
logger.info('=> Loading custom .babelrc');
} catch (e) {
logger.error(`=> Error parsing .babelrc file: ${e.message}`);
throw e;
}
}
if (!config) return null;
// Remove react-hmre preset.
// It causes issues with react-storybook.
// We don't really need it.
// Earlier, we fix this by runnign storybook in the production mode.
// But, that hide some useful debug messages.
if (config.presets) {
removeReactHmre(config.presets);
}
if (config.env && config.env.development && config.env.development.presets) {
removeReactHmre(config.env.development.presets);
}
return config;
}
// `baseConfig` is a webpack configuration bundled with storybook.
// React Storybook will look in the `configDir` directory
// (inside working directory) if a config path is not provided.
export default function (configType, baseConfig, configDir) {
const config = baseConfig;
// Search for a .babelrc in the config directory, then the module root
// directory. If found, use that to extend webpack configurations.
let babelConfig = loadBabelConfig(path.resolve(configDir, '.babelrc'));
let inConfigDir = true;
if (!babelConfig) {
babelConfig = loadBabelConfig('.babelrc');
inConfigDir = false;
}
if (babelConfig) {
// If the custom config uses babel's `extends` clause, then replace it with
// an absolute path. `extends` will not work unless we do this.
if (babelConfig.extends) {
babelConfig.extends = inConfigDir ?
path.resolve(configDir, babelConfig.extends) :
path.resolve(babelConfig.extends);
}
config.module.loaders[0].query = babelConfig;
}
// Check whether a config.js file exists inside the storybook
// config directory and throw an error if it's not.
const storybookConfigPath = path.resolve(configDir, 'config.js');
if (!fs.existsSync(storybookConfigPath)) {
const err = new Error(`=> Create a storybook config file in "${configDir}/config.js".`);
throw err;
}
config.entry.preview.push(require.resolve(storybookConfigPath));
// Check whether addons.js file exists inside the storybook.
// Load the default addons.js file if it's missing.
const storybookDefaultAddonsPath = path.resolve(__dirname, 'addons.js');
const storybookCustomAddonsPath = path.resolve(configDir, 'addons.js');
if (fs.existsSync(storybookCustomAddonsPath)) {
logger.info('=> Loading custom addons config.');
config.entry.manager.unshift(storybookCustomAddonsPath);
} else {
config.entry.manager.unshift(storybookDefaultAddonsPath);
}
// 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');
if (!fs.existsSync(customConfigPath)) {
logger.info('=> Using default webpack setup based on "Create React App".');
customConfigPath = path.resolve(__dirname, './config/defaults/webpack.config.js');
}
const customConfig = require(customConfigPath);
if (typeof customConfig === 'function') {
logger.info('=> Loading custom webpack config (full-control mode).');
return customConfig(config, configType);
}
logger.info('=> Loading custom webpack config.');
customConfig.module = customConfig.module || {};
return {
...customConfig,
// We'll always load our configurations after the custom config.
// So, we'll always load the stuff we need.
...config,
// We need to use our and custom plugins.
plugins: [
...config.plugins,
...customConfig.plugins || [],
],
module: {
...config.module,
// We need to use our and custom loaders.
...customConfig.module,
loaders: [
...config.module.loaders,
...customConfig.module.loaders || [],
],
},
resolve: {
...customConfig.resolve,
alias: {
...config.alias,
...customConfig.alias,
}
}
};
}