React components style guide generator with live development server and interactive documentation
—
Custom webpack loaders and configuration utilities that enable React Styleguidist to process React components, extract documentation, and generate interactive styleguides with hot reloading support.
Generate complete webpack configurations for building and serving styleguides.
/**
* Generate webpack configuration for Styleguidist
* @param config - Styleguidist configuration object
* @param env - Target environment
* @returns Complete webpack configuration
*/
function makeWebpackConfig(
config: SanitizedStyleguidistConfig,
env: 'development' | 'production' | 'none'
): webpack.Configuration;Usage Examples:
const makeWebpackConfig = require('react-styleguidist/lib/scripts/make-webpack-config').default;
const getConfig = require('react-styleguidist/lib/scripts/config').default;
// Generate production config
const styleguidistConfig = getConfig();
const webpackConfig = makeWebpackConfig(styleguidistConfig, 'production');
console.log('Entry points:', webpackConfig.entry);
console.log('Output directory:', webpackConfig.output.path);
console.log('Loaders:', webpackConfig.module.rules.length);
// Use with custom webpack setup
const webpack = require('webpack');
const compiler = webpack(webpackConfig);React Styleguidist includes specialized webpack loaders for processing components and generating the styleguide interface.
Generates the main styleguide bundle with sections and components data.
/**
* Styleguide loader - generates main styleguide entry point
* Applied automatically to styleguide index file
* Exports configuration and section data for client
*/
// Loader is applied automatically, no direct usage needed
// File: src/loaders/styleguide-loader.ts
interface StyleguidistLoaderContext extends LoaderContext<OptionsType> {
_styleguidist: SanitizedStyleguidistConfig;
}Generated Output Example:
// Auto-generated by styleguide-loader
module.exports = {
config: {
title: 'Component Library',
showCode: true,
showUsage: true,
// ... configuration options
},
sections: [
{
name: 'Components',
components: [
// Component data with props and examples
]
}
]
};Extracts component props and documentation using react-docgen.
/**
* Props loader - extracts component documentation
* Applied automatically to component files
* Uses react-docgen to parse components and extract props
*/
// File: src/loaders/props-loader.ts
interface PropsLoaderOutput {
displayName: string;
description?: string;
props: Record<string, PropDescriptor>;
examples: Example[];
methods: MethodDescriptor[];
}
interface PropDescriptor {
name: string;
type: TypeDescriptor;
required: boolean;
description?: string;
defaultValue?: { value: string; computed: boolean };
}Generated Output Example:
// Auto-generated by props-loader for Button.jsx
module.exports = {
displayName: 'Button',
description: 'A reusable button component',
props: {
children: {
type: { name: 'node' },
required: true,
description: 'Button content'
},
variant: {
type: { name: 'enum', value: ['primary', 'secondary'] },
required: false,
defaultValue: { value: 'primary', computed: false }
}
},
examples: [
{
type: 'code',
content: '<Button>Click me</Button>',
evalInContext: function(code) { /* ... */ }
}
]
};Processes markdown examples and prepares them for execution in the browser.
/**
* Examples loader - processes markdown examples
* Applied automatically to example files (.md)
* Converts markdown code blocks to executable examples
*/
// File: src/loaders/examples-loader.ts
interface ExampleLoaderOutput {
type: 'code' | 'markdown';
content: string;
evalInContext?: Function;
compiled?: string;
}Modify the generated webpack configuration to meet your project's needs.
interface WebpackCustomization {
/** Safely update webpack configuration */
updateWebpackConfig?: (config: webpack.Configuration) => webpack.Configuration;
/** Advanced webpack config modification (use with caution) */
dangerouslyUpdateWebpackConfig?: (
config: webpack.Configuration,
env: string
) => webpack.Configuration;
/** Add custom webpack plugins */
configureServer?: (server: WebpackDevServer, env: string) => void;
}Usage Examples:
// styleguide.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
// Safe configuration updates
updateWebpackConfig(config) {
// Add TypeScript support
config.module.rules.push({
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
});
// Add resolve extensions
config.resolve.extensions.push('.ts', '.tsx');
// Add source maps for development
if (config.mode === 'development') {
config.devtool = 'eval-source-map';
}
// Add custom plugin
config.plugins.push(
new webpack.DefinePlugin({
STYLEGUIDE_VERSION: JSON.stringify(process.env.npm_package_version)
})
);
return config;
},
// Advanced configuration (careful use required)
dangerouslyUpdateWebpackConfig(config, env) {
// Modify entry points
if (env === 'development') {
config.entry = [
'webpack-hot-middleware/client',
config.entry
];
}
// Replace specific loaders
config.module.rules = config.module.rules.map(rule => {
if (rule.test && rule.test.toString().includes('css')) {
return {
...rule,
use: [
'style-loader',
{
loader: 'css-loader',
options: { modules: true }
}
]
};
}
return rule;
});
return config;
},
// Configure development server
configureServer(server, env) {
// Add custom middleware
server.app.use('/api', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
// Add custom routes
server.app.get('/health', (req, res) => {
res.json({ status: 'ok', env });
});
}
};Custom Loader Integration:
module.exports = {
updateWebpackConfig(config) {
// Add custom loader for processing special files
config.module.rules.push({
test: /\.stories\.js$/,
use: [
{
loader: path.resolve('./loaders/stories-loader.js'),
options: {
extractExamples: true
}
}
]
});
return config;
}
};Multi-Environment Configuration:
const isDev = process.env.NODE_ENV === 'development';
const isProd = process.env.NODE_ENV === 'production';
module.exports = {
updateWebpackConfig(config) {
if (isDev) {
// Development optimizations
config.cache = {
type: 'filesystem',
buildDependencies: {
config: [__filename]
}
};
config.optimization.splitChunks = false;
}
if (isProd) {
// Production optimizations
config.optimization.minimize = true;
config.optimization.splitChunks = {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
};
}
return config;
}
};Asset Processing Configuration:
module.exports = {
updateWebpackConfig(config) {
// Handle different asset types
const assetRules = [
{
test: /\.(png|jpe?g|gif|svg)$/i,
type: 'asset/resource',
generator: {
filename: 'images/[name].[hash][ext]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[hash][ext]'
}
},
{
test: /\.(csv|tsv)$/i,
use: ['csv-loader']
}
];
config.module.rules.push(...assetRules);
return config;
}
};Access Styleguidist configuration and utilities within custom loaders.
interface StyleguidistLoaderContext extends webpack.LoaderContext<any> {
/** Styleguidist configuration available to loaders */
_styleguidist: SanitizedStyleguidistConfig;
}
// Utility functions available in loader context
interface LoaderUtilities {
/** Parse component using react-docgen */
getProps: (filePath: string, code: string) => PropsObject;
/** Get components matching patterns */
getComponents: (patterns: string | string[]) => string[];
/** Process markdown content */
processMarkdown: (content: string) => ProcessedMarkdown;
/** Compile code examples */
compileExamples: (examples: Example[]) => CompiledExample[];
}Custom Loader Example:
// custom-component-loader.js
module.exports = function(source) {
const config = this._styleguidist;
const callback = this.async();
// Access Styleguidist configuration
const { components, styleguideDir } = config;
// Process source code
const processedSource = source.replace(
/\/\* @styleguidist-ignore \*\//g,
''
);
// Add custom metadata
const componentInfo = {
filePath: this.resourcePath,
lastModified: new Date().toISOString(),
styleguidistConfig: {
showCode: config.showCode,
showUsage: config.showUsage
}
};
const output = `
${processedSource}
// Injected by custom loader
export const __styleguidistMeta = ${JSON.stringify(componentInfo)};
`;
callback(null, output);
};interface WebpackIntegrationConfig {
/** Base webpack configuration */
webpackConfig?: webpack.Configuration | ((env?: string) => webpack.Configuration);
/** Safe configuration updates */
updateWebpackConfig?: (config: webpack.Configuration) => webpack.Configuration;
/** Advanced configuration modification */
dangerouslyUpdateWebpackConfig?: (config: webpack.Configuration, env: string) => webpack.Configuration;
/** Module resolution aliases */
moduleAliases?: Record<string, string>;
/** Additional context dependencies for watching */
contextDependencies?: string[];
/** Development server configuration */
configureServer?: (server: WebpackDevServer, env: string) => void;
}Install with Tessl CLI
npx tessl i tessl/npm-react-styleguidist