0
# Environment & CLI Utilities
1
2
Environment variable processing, temporary file management, and CLI utility functions for Storybook development tools and build processes.
3
4
## Capabilities
5
6
### Environment Variable Processing
7
8
Load and process Storybook-specific environment variables with proper formatting and validation.
9
10
```typescript { .api }
11
/**
12
* Load and process STORYBOOK_* environment variables
13
* @param options - Environment loading options
14
* @returns Object with processed environment variables
15
*/
16
function loadEnvs(options?: {
17
production?: boolean;
18
}): Record<string, string>;
19
20
/**
21
* Convert environment object to stringified values for webpack DefinePlugin
22
* @param raw - Raw environment variable object
23
* @returns Object with stringified values
24
*/
25
function stringifyEnvs(raw: Record<string, any>): Record<string, string>;
26
27
/**
28
* Convert environment object to process.env.KEY format strings
29
* @param raw - Raw environment variable object
30
* @returns Object with process.env prefixed keys
31
*/
32
function stringifyProcessEnvs(raw: Record<string, any>): Record<string, string>;
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import { loadEnvs, stringifyEnvs } from "@storybook/core-common";
39
40
// Load Storybook environment variables
41
const envVars = loadEnvs({ production: false });
42
console.log(envVars);
43
// {
44
// STORYBOOK_API_URL: 'https://api.example.com',
45
// STORYBOOK_THEME: 'dark',
46
// NODE_ENV: 'development'
47
// }
48
49
// Prepare for webpack DefinePlugin
50
const webpackEnv = stringifyEnvs(envVars);
51
console.log(webpackEnv);
52
// {
53
// STORYBOOK_API_URL: '"https://api.example.com"',
54
// STORYBOOK_THEME: '"dark"',
55
// NODE_ENV: '"development"'
56
// }
57
```
58
59
### Temporary File Management
60
61
Create and manage temporary files and directories for build processes and development workflows.
62
63
```typescript { .api }
64
/**
65
* Create temporary directory with optional prefix
66
* @param options - Directory creation options
67
* @returns Promise resolving to temporary directory path
68
*/
69
function temporaryDirectory(options?: {
70
prefix?: string;
71
}): Promise<string>;
72
73
/**
74
* Create temporary file with optional name and extension
75
* @param options - File creation options
76
* @returns Promise resolving to temporary file path
77
*/
78
function temporaryFile(options?: {
79
name?: string;
80
extension?: string;
81
}): Promise<string>;
82
83
interface FileOptions {
84
name?: string;
85
extension?: string;
86
}
87
```
88
89
**Usage Examples:**
90
91
```typescript
92
import { temporaryDirectory, temporaryFile } from "@storybook/core-common";
93
94
// Create temporary directory for build artifacts
95
const tempDir = await temporaryDirectory({ prefix: 'storybook-build-' });
96
console.log(tempDir); // '/tmp/storybook-build-abc123'
97
98
// Create temporary config file
99
const tempConfig = await temporaryFile({
100
name: 'webpack.config',
101
extension: '.js'
102
});
103
console.log(tempConfig); // '/tmp/webpack.config.abc123.js'
104
105
// Use for build processes
106
const buildDir = await temporaryDirectory({ prefix: 'sb-output-' });
107
await runBuildProcess({ outputDir: buildDir });
108
```
109
110
### CLI Parsing Utilities
111
112
Parse and process command-line arguments and configuration strings.
113
114
```typescript { .api }
115
/**
116
* Parse comma-separated string into array of trimmed strings
117
* @param str - Comma-separated string
118
* @returns Array of parsed strings
119
*/
120
function parseList(str: string): string[];
121
122
/**
123
* Get normalized Storybook version from package manager
124
* @param packageManager - Package manager instance
125
* @returns Promise resolving to coerced version string
126
*/
127
function getCoercedStorybookVersion(packageManager: any): Promise<string>;
128
129
/**
130
* Load environment variables into program configuration
131
* @param program - CLI program instance
132
* @param configEnv - Environment configuration
133
* @returns Updated program configuration
134
*/
135
function getEnvConfig(program: any, configEnv: any): any;
136
```
137
138
**Usage Examples:**
139
140
```typescript
141
import { parseList, getCoercedStorybookVersion } from "@storybook/core-common";
142
143
// Parse comma-separated addons list
144
const addons = parseList('@storybook/addon-docs, @storybook/addon-controls, custom-addon');
145
console.log(addons); // ['@storybook/addon-docs', '@storybook/addon-controls', 'custom-addon']
146
147
// Parse CLI flags
148
const frameworks = parseList('react,vue,angular');
149
console.log(frameworks); // ['react', 'vue', 'angular']
150
151
// Get Storybook version
152
const version = await getCoercedStorybookVersion(packageManager);
153
console.log(version); // '8.6.14'
154
```
155
156
### Logging Utilities
157
158
Create managed log streams and check package classifications.
159
160
```typescript { .api }
161
/**
162
* Create managed log file stream with move/remove capabilities
163
* @param logFileName - Optional log file name
164
* @returns Log stream with management methods
165
*/
166
function createLogStream(logFileName?: string): {
167
stream: NodeJS.WritableStream;
168
moveLogFile: (targetPath: string) => Promise<void>;
169
removeLogFile: () => Promise<void>;
170
};
171
172
/**
173
* Check if package is a Storybook core package
174
* @param pkg - Package name to check
175
* @returns True if package is a Storybook core package
176
*/
177
function isCorePackage(pkg: string): boolean;
178
```
179
180
**Usage Examples:**
181
182
```typescript
183
import { createLogStream, isCorePackage } from "@storybook/core-common";
184
185
// Create managed log stream
186
const logStream = createLogStream('storybook-build.log');
187
188
// Write to log
189
logStream.stream.write('Starting build process...\n');
190
logStream.stream.write(`Build completed at ${new Date()}\n`);
191
192
// Move log file to final location
193
await logStream.moveLogFile('./logs/build-final.log');
194
195
// Check if packages are core Storybook packages
196
console.log(isCorePackage('@storybook/react')); // true
197
console.log(isCorePackage('@storybook/addon-docs')); // true
198
console.log(isCorePackage('lodash')); // false
199
```
200
201
### Storybook Configuration Extraction
202
203
Extract Storybook CLI configuration from npm scripts.
204
205
```typescript { .api }
206
/**
207
* Extract Storybook CLI flags from npm script configuration
208
* @param script - npm script content
209
* @param shortName - Short flag name (e.g., 'p')
210
* @param longName - Long flag name (e.g., 'port')
211
* @returns Extracted configuration value or undefined
212
*/
213
function getStorybookConfiguration(
214
script: string,
215
shortName: string,
216
longName: string
217
): string | undefined;
218
```
219
220
**Usage Example:**
221
222
```typescript
223
import { getStorybookConfiguration } from "@storybook/core-common";
224
225
// Extract port from npm script
226
const script = 'storybook dev -p 6006 --quiet';
227
const port = getStorybookConfiguration(script, 'p', 'port');
228
console.log(port); // '6006'
229
230
// Extract other flags
231
const quietFlag = getStorybookConfiguration(script, '', 'quiet');
232
console.log(quietFlag); // 'true'
233
```
234
235
## Advanced Usage Patterns
236
237
### Environment-Aware Configuration
238
239
```typescript
240
import { loadEnvs, stringifyEnvs } from "@storybook/core-common";
241
242
function createEnvironmentConfig(isProduction: boolean) {
243
// Load environment variables
244
const envVars = loadEnvs({ production: isProduction });
245
246
// Add build-specific variables
247
const buildEnv = {
248
...envVars,
249
STORYBOOK_BUILD_TIME: new Date().toISOString(),
250
STORYBOOK_BUILD_MODE: isProduction ? 'production' : 'development'
251
};
252
253
// Prepare for webpack
254
return stringifyEnvs(buildEnv);
255
}
256
257
// Usage in webpack config
258
const definePluginEnv = createEnvironmentConfig(process.env.NODE_ENV === 'production');
259
```
260
261
### Build Process Management
262
263
```typescript
264
import {
265
temporaryDirectory,
266
temporaryFile,
267
createLogStream
268
} from "@storybook/core-common";
269
270
async function managedBuildProcess(buildOptions: any) {
271
// Create temporary workspace
272
const workDir = await temporaryDirectory({ prefix: 'storybook-build-' });
273
274
// Create build log
275
const logStream = createLogStream('build.log');
276
277
try {
278
// Create temporary config
279
const configFile = await temporaryFile({
280
name: 'build.config',
281
extension: '.json'
282
});
283
284
// Write config
285
await fs.writeFile(configFile, JSON.stringify(buildOptions, null, 2));
286
287
// Run build process
288
logStream.stream.write('Starting build...\n');
289
const result = await runBuild({
290
workDir,
291
configFile,
292
logStream: logStream.stream
293
});
294
295
// Move log to final location
296
await logStream.moveLogFile('./logs/build-success.log');
297
298
return result;
299
300
} catch (error) {
301
logStream.stream.write(`Build failed: ${error.message}\n`);
302
await logStream.moveLogFile('./logs/build-error.log');
303
throw error;
304
}
305
}
306
```
307
308
### CLI Integration
309
310
```typescript
311
import { parseList, getEnvConfig } from "@storybook/core-common";
312
import { program } from 'commander';
313
314
// Set up CLI with environment integration
315
program
316
.option('--addons <addons>', 'Comma-separated list of addons')
317
.option('--port <port>', 'Development server port')
318
.action((options) => {
319
// Parse addon list
320
if (options.addons) {
321
options.addons = parseList(options.addons);
322
}
323
324
// Load environment configuration
325
const envConfig = getEnvConfig(program, process.env);
326
327
// Merge configurations
328
const finalConfig = { ...envConfig, ...options };
329
330
console.log('Final configuration:', finalConfig);
331
});
332
```
333
334
## Supporting Types
335
336
```typescript { .api }
337
interface EnvironmentOptions {
338
/** Whether to load production-specific environment variables */
339
production?: boolean;
340
}
341
342
interface TempDirectoryOptions {
343
/** Prefix for temporary directory name */
344
prefix?: string;
345
}
346
347
interface TempFileOptions {
348
/** Specific file name (without extension) */
349
name?: string;
350
/** File extension (with or without leading dot) */
351
extension?: string;
352
}
353
354
interface LogStream {
355
/** Writable stream for log output */
356
stream: NodeJS.WritableStream;
357
/** Move log file to target path */
358
moveLogFile: (targetPath: string) => Promise<void>;
359
/** Remove log file */
360
removeLogFile: () => Promise<void>;
361
}
362
```