0
# Webpack Integration
1
2
Custom webpack loaders and configuration utilities that enable React Styleguidist to process React components, extract documentation, and generate interactive styleguides with hot reloading support.
3
4
## Capabilities
5
6
### Webpack Configuration Generation
7
8
Generate complete webpack configurations for building and serving styleguides.
9
10
```typescript { .api }
11
/**
12
* Generate webpack configuration for Styleguidist
13
* @param config - Styleguidist configuration object
14
* @param env - Target environment
15
* @returns Complete webpack configuration
16
*/
17
function makeWebpackConfig(
18
config: SanitizedStyleguidistConfig,
19
env: 'development' | 'production' | 'none'
20
): webpack.Configuration;
21
```
22
23
**Usage Examples:**
24
25
```javascript
26
const makeWebpackConfig = require('react-styleguidist/lib/scripts/make-webpack-config').default;
27
const getConfig = require('react-styleguidist/lib/scripts/config').default;
28
29
// Generate production config
30
const styleguidistConfig = getConfig();
31
const webpackConfig = makeWebpackConfig(styleguidistConfig, 'production');
32
33
console.log('Entry points:', webpackConfig.entry);
34
console.log('Output directory:', webpackConfig.output.path);
35
console.log('Loaders:', webpackConfig.module.rules.length);
36
37
// Use with custom webpack setup
38
const webpack = require('webpack');
39
const compiler = webpack(webpackConfig);
40
```
41
42
### Styleguidist Loaders
43
44
React Styleguidist includes specialized webpack loaders for processing components and generating the styleguide interface.
45
46
#### Styleguide Loader
47
48
Generates the main styleguide bundle with sections and components data.
49
50
```typescript { .api }
51
/**
52
* Styleguide loader - generates main styleguide entry point
53
* Applied automatically to styleguide index file
54
* Exports configuration and section data for client
55
*/
56
// Loader is applied automatically, no direct usage needed
57
// File: src/loaders/styleguide-loader.ts
58
59
interface StyleguidistLoaderContext extends LoaderContext<OptionsType> {
60
_styleguidist: SanitizedStyleguidistConfig;
61
}
62
```
63
64
**Generated Output Example:**
65
66
```javascript
67
// Auto-generated by styleguide-loader
68
module.exports = {
69
config: {
70
title: 'Component Library',
71
showCode: true,
72
showUsage: true,
73
// ... configuration options
74
},
75
sections: [
76
{
77
name: 'Components',
78
components: [
79
// Component data with props and examples
80
]
81
}
82
]
83
};
84
```
85
86
#### Props Loader
87
88
Extracts component props and documentation using react-docgen.
89
90
```typescript { .api }
91
/**
92
* Props loader - extracts component documentation
93
* Applied automatically to component files
94
* Uses react-docgen to parse components and extract props
95
*/
96
// File: src/loaders/props-loader.ts
97
98
interface PropsLoaderOutput {
99
displayName: string;
100
description?: string;
101
props: Record<string, PropDescriptor>;
102
examples: Example[];
103
methods: MethodDescriptor[];
104
}
105
106
interface PropDescriptor {
107
name: string;
108
type: TypeDescriptor;
109
required: boolean;
110
description?: string;
111
defaultValue?: { value: string; computed: boolean };
112
}
113
```
114
115
**Generated Output Example:**
116
117
```javascript
118
// Auto-generated by props-loader for Button.jsx
119
module.exports = {
120
displayName: 'Button',
121
description: 'A reusable button component',
122
props: {
123
children: {
124
type: { name: 'node' },
125
required: true,
126
description: 'Button content'
127
},
128
variant: {
129
type: { name: 'enum', value: ['primary', 'secondary'] },
130
required: false,
131
defaultValue: { value: 'primary', computed: false }
132
}
133
},
134
examples: [
135
{
136
type: 'code',
137
content: '<Button>Click me</Button>',
138
evalInContext: function(code) { /* ... */ }
139
}
140
]
141
};
142
```
143
144
#### Examples Loader
145
146
Processes markdown examples and prepares them for execution in the browser.
147
148
```typescript { .api }
149
/**
150
* Examples loader - processes markdown examples
151
* Applied automatically to example files (.md)
152
* Converts markdown code blocks to executable examples
153
*/
154
// File: src/loaders/examples-loader.ts
155
156
interface ExampleLoaderOutput {
157
type: 'code' | 'markdown';
158
content: string;
159
evalInContext?: Function;
160
compiled?: string;
161
}
162
```
163
164
### Webpack Configuration Customization
165
166
Modify the generated webpack configuration to meet your project's needs.
167
168
```typescript { .api }
169
interface WebpackCustomization {
170
/** Safely update webpack configuration */
171
updateWebpackConfig?: (config: webpack.Configuration) => webpack.Configuration;
172
173
/** Advanced webpack config modification (use with caution) */
174
dangerouslyUpdateWebpackConfig?: (
175
config: webpack.Configuration,
176
env: string
177
) => webpack.Configuration;
178
179
/** Add custom webpack plugins */
180
configureServer?: (server: WebpackDevServer, env: string) => void;
181
}
182
```
183
184
**Usage Examples:**
185
186
```javascript
187
// styleguide.config.js
188
const path = require('path');
189
const webpack = require('webpack');
190
191
module.exports = {
192
// Safe configuration updates
193
updateWebpackConfig(config) {
194
// Add TypeScript support
195
config.module.rules.push({
196
test: /\.tsx?$/,
197
use: 'ts-loader',
198
exclude: /node_modules/
199
});
200
201
// Add resolve extensions
202
config.resolve.extensions.push('.ts', '.tsx');
203
204
// Add source maps for development
205
if (config.mode === 'development') {
206
config.devtool = 'eval-source-map';
207
}
208
209
// Add custom plugin
210
config.plugins.push(
211
new webpack.DefinePlugin({
212
STYLEGUIDE_VERSION: JSON.stringify(process.env.npm_package_version)
213
})
214
);
215
216
return config;
217
},
218
219
// Advanced configuration (careful use required)
220
dangerouslyUpdateWebpackConfig(config, env) {
221
// Modify entry points
222
if (env === 'development') {
223
config.entry = [
224
'webpack-hot-middleware/client',
225
config.entry
226
];
227
}
228
229
// Replace specific loaders
230
config.module.rules = config.module.rules.map(rule => {
231
if (rule.test && rule.test.toString().includes('css')) {
232
return {
233
...rule,
234
use: [
235
'style-loader',
236
{
237
loader: 'css-loader',
238
options: { modules: true }
239
}
240
]
241
};
242
}
243
return rule;
244
});
245
246
return config;
247
},
248
249
// Configure development server
250
configureServer(server, env) {
251
// Add custom middleware
252
server.app.use('/api', (req, res, next) => {
253
res.header('Access-Control-Allow-Origin', '*');
254
next();
255
});
256
257
// Add custom routes
258
server.app.get('/health', (req, res) => {
259
res.json({ status: 'ok', env });
260
});
261
}
262
};
263
```
264
265
### Advanced Webpack Integration Patterns
266
267
**Custom Loader Integration:**
268
269
```javascript
270
module.exports = {
271
updateWebpackConfig(config) {
272
// Add custom loader for processing special files
273
config.module.rules.push({
274
test: /\.stories\.js$/,
275
use: [
276
{
277
loader: path.resolve('./loaders/stories-loader.js'),
278
options: {
279
extractExamples: true
280
}
281
}
282
]
283
});
284
285
return config;
286
}
287
};
288
```
289
290
**Multi-Environment Configuration:**
291
292
```javascript
293
const isDev = process.env.NODE_ENV === 'development';
294
const isProd = process.env.NODE_ENV === 'production';
295
296
module.exports = {
297
updateWebpackConfig(config) {
298
if (isDev) {
299
// Development optimizations
300
config.cache = {
301
type: 'filesystem',
302
buildDependencies: {
303
config: [__filename]
304
}
305
};
306
307
config.optimization.splitChunks = false;
308
}
309
310
if (isProd) {
311
// Production optimizations
312
config.optimization.minimize = true;
313
config.optimization.splitChunks = {
314
chunks: 'all',
315
cacheGroups: {
316
vendor: {
317
test: /[\\/]node_modules[\\/]/,
318
name: 'vendors',
319
chunks: 'all'
320
}
321
}
322
};
323
}
324
325
return config;
326
}
327
};
328
```
329
330
**Asset Processing Configuration:**
331
332
```javascript
333
module.exports = {
334
updateWebpackConfig(config) {
335
// Handle different asset types
336
const assetRules = [
337
{
338
test: /\.(png|jpe?g|gif|svg)$/i,
339
type: 'asset/resource',
340
generator: {
341
filename: 'images/[name].[hash][ext]'
342
}
343
},
344
{
345
test: /\.(woff|woff2|eot|ttf|otf)$/i,
346
type: 'asset/resource',
347
generator: {
348
filename: 'fonts/[name].[hash][ext]'
349
}
350
},
351
{
352
test: /\.(csv|tsv)$/i,
353
use: ['csv-loader']
354
}
355
];
356
357
config.module.rules.push(...assetRules);
358
359
return config;
360
}
361
};
362
```
363
364
### Loader Context and Utilities
365
366
Access Styleguidist configuration and utilities within custom loaders.
367
368
```typescript { .api }
369
interface StyleguidistLoaderContext extends webpack.LoaderContext<any> {
370
/** Styleguidist configuration available to loaders */
371
_styleguidist: SanitizedStyleguidistConfig;
372
}
373
374
// Utility functions available in loader context
375
interface LoaderUtilities {
376
/** Parse component using react-docgen */
377
getProps: (filePath: string, code: string) => PropsObject;
378
379
/** Get components matching patterns */
380
getComponents: (patterns: string | string[]) => string[];
381
382
/** Process markdown content */
383
processMarkdown: (content: string) => ProcessedMarkdown;
384
385
/** Compile code examples */
386
compileExamples: (examples: Example[]) => CompiledExample[];
387
}
388
```
389
390
**Custom Loader Example:**
391
392
```javascript
393
// custom-component-loader.js
394
module.exports = function(source) {
395
const config = this._styleguidist;
396
const callback = this.async();
397
398
// Access Styleguidist configuration
399
const { components, styleguideDir } = config;
400
401
// Process source code
402
const processedSource = source.replace(
403
/\/\* @styleguidist-ignore \*\//g,
404
''
405
);
406
407
// Add custom metadata
408
const componentInfo = {
409
filePath: this.resourcePath,
410
lastModified: new Date().toISOString(),
411
styleguidistConfig: {
412
showCode: config.showCode,
413
showUsage: config.showUsage
414
}
415
};
416
417
const output = `
418
${processedSource}
419
420
// Injected by custom loader
421
export const __styleguidistMeta = ${JSON.stringify(componentInfo)};
422
`;
423
424
callback(null, output);
425
};
426
```
427
428
## Configuration Reference
429
430
```typescript { .api }
431
interface WebpackIntegrationConfig {
432
/** Base webpack configuration */
433
webpackConfig?: webpack.Configuration | ((env?: string) => webpack.Configuration);
434
435
/** Safe configuration updates */
436
updateWebpackConfig?: (config: webpack.Configuration) => webpack.Configuration;
437
438
/** Advanced configuration modification */
439
dangerouslyUpdateWebpackConfig?: (config: webpack.Configuration, env: string) => webpack.Configuration;
440
441
/** Module resolution aliases */
442
moduleAliases?: Record<string, string>;
443
444
/** Additional context dependencies for watching */
445
contextDependencies?: string[];
446
447
/** Development server configuration */
448
configureServer?: (server: WebpackDevServer, env: string) => void;
449
}
450
```