or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

config-management.mdcsf-processing.mdindex.mdstory-enhancement.mdtesting-integration.md

config-management.mddocs/

0

# Configuration Management

1

2

Parse and manipulate Storybook configuration files including main.js, preview.js, and other config files. Supports both ESM and CommonJS formats with comprehensive field manipulation capabilities.

3

4

## Capabilities

5

6

### Loading Configuration Files

7

8

Parse configuration code into a structured ConfigFile object for analysis and manipulation.

9

10

```typescript { .api }

11

/**

12

* Parse configuration code into a ConfigFile instance

13

* @param code - The configuration source code as a string

14

* @param fileName - Optional file name for error reporting

15

* @returns ConfigFile instance ready for parsing

16

*/

17

function loadConfig(code: string, fileName?: string): ConfigFile;

18

```

19

20

**Usage Examples:**

21

22

```typescript

23

import { loadConfig } from "@storybook/csf-tools";

24

25

// Parse Storybook main.js configuration

26

const mainConfig = `

27

module.exports = {

28

stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],

29

addons: ['@storybook/addon-essentials'],

30

framework: '@storybook/react-vite'

31

};

32

`;

33

34

const config = loadConfig(mainConfig, 'main.js').parse();

35

```

36

37

### Reading Configuration Files

38

39

Read and parse configuration files directly from the filesystem.

40

41

```typescript { .api }

42

/**

43

* Read and parse a configuration file from the filesystem

44

* @param fileName - Path to the configuration file

45

* @returns Promise resolving to parsed ConfigFile

46

*/

47

function readConfig(fileName: string): Promise<ConfigFile>;

48

```

49

50

**Usage Examples:**

51

52

```typescript

53

import { readConfig } from "@storybook/csf-tools";

54

55

// Read and parse main.js

56

const config = await readConfig('.storybook/main.js');

57

58

// Access configuration values

59

const stories = config.getFieldValue(['stories']);

60

const addons = config.getNamesFromPath(['addons']);

61

```

62

63

### Writing Configuration Files

64

65

Write ConfigFile objects back to the filesystem as formatted code.

66

67

```typescript { .api }

68

/**

69

* Write a ConfigFile to the filesystem

70

* @param config - The ConfigFile instance to write

71

* @param fileName - Optional output file path (uses config.fileName if not provided)

72

* @returns Promise that resolves when file is written

73

*/

74

function writeConfig(config: ConfigFile, fileName?: string): Promise<void>;

75

```

76

77

### Code Generation

78

79

Generate formatted code from ConfigFile instances.

80

81

```typescript { .api }

82

/**

83

* Generate formatted code from a ConfigFile

84

* @param config - The ConfigFile instance to format

85

* @returns Generated configuration code as string

86

*/

87

function formatConfig(config: ConfigFile): string;

88

89

/**

90

* Generate code with style preservation using recast

91

* @param config - The ConfigFile instance to print

92

* @param options - Recast formatting options

93

* @returns Object with code and optional source map

94

*/

95

function printConfig(config: ConfigFile, options?: RecastOptions): PrintResultType;

96

```

97

98

### ConfigFile Class

99

100

The core class for representing and manipulating configuration files.

101

102

```typescript { .api }

103

class ConfigFile {

104

/** Babel AST representation of the file */

105

readonly _ast: t.File;

106

/** Original source code */

107

readonly _code: string;

108

/** Parsed exports from the configuration */

109

readonly _exports: Record<string, t.Expression>;

110

/** Main exports object if present */

111

readonly _exportsObject?: t.ObjectExpression;

112

/** Optional file name */

113

fileName?: string;

114

/** Whether file has a default export */

115

hasDefaultExport: boolean;

116

117

constructor(ast: t.File, code: string, fileName?: string);

118

119

/**

120

* Parse the AST to extract configuration exports

121

* @returns Self for method chaining

122

*/

123

parse(): ConfigFile;

124

125

/**

126

* Get AST node at the specified path

127

* @param path - Array of property names representing the path

128

* @returns AST node if found, undefined otherwise

129

*/

130

getFieldNode(path: string[]): t.Node | undefined;

131

132

/**

133

* Get evaluated value at the specified path

134

* @param path - Array of property names representing the path

135

* @returns Evaluated value if found, undefined otherwise

136

*/

137

getFieldValue<T = any>(path: string[]): T | undefined;

138

139

/**

140

* Get value at path with error handling

141

* @param path - Array of property names representing the path

142

* @returns Value if found and evaluable, undefined otherwise

143

*/

144

getSafeFieldValue(path: string[]): any;

145

146

/**

147

* Set AST node at the specified path

148

* @param path - Array of property names representing the path

149

* @param expr - AST expression to set

150

*/

151

setFieldNode(path: string[], expr: t.Expression): void;

152

153

/**

154

* Set value at the specified path

155

* @param path - Array of property names representing the path

156

* @param value - Value to set (will be converted to AST)

157

*/

158

setFieldValue(path: string[], value: any): void;

159

160

/**

161

* Remove field at the specified path

162

* @param path - Array of property names representing the path

163

*/

164

removeField(path: string[]): void;

165

}

166

```

167

168

### Framework and Addon Management

169

170

Specialized methods for working with Storybook framework and addon configurations.

171

172

```typescript { .api }

173

/**

174

* Get name from framework or addon configuration

175

* Supports both string format ("framework-name") and object format ({ name: "framework-name", options: {} })

176

* @param path - Path to the configuration field

177

* @returns Framework or addon name if found

178

*/

179

getNameFromPath(path: string[]): string | undefined;

180

181

/**

182

* Get array of names from addon configuration

183

* @param path - Path to the addons array

184

* @returns Array of addon names

185

*/

186

getNamesFromPath(path: string[]): string[] | undefined;

187

```

188

189

**Usage Examples:**

190

191

```typescript

192

// Get framework name

193

const frameworkName = config.getNameFromPath(['framework']);

194

195

// Get all addon names

196

const addonNames = config.getNamesFromPath(['addons']);

197

198

// Get stories configuration

199

const stories = config.getFieldValue(['stories']);

200

```

201

202

### Array Manipulation

203

204

Methods for working with array fields like stories and addons.

205

206

```typescript { .api }

207

/**

208

* Append a value to an array field

209

* @param path - Path to the array field

210

* @param value - Value to append

211

*/

212

appendValueToArray(path: string[], value: any): void;

213

214

/**

215

* Append an AST node to an array field

216

* @param path - Path to the array field

217

* @param node - AST expression to append

218

*/

219

appendNodeToArray(path: string[], node: t.Expression): void;

220

221

/**

222

* Remove entry from array by name (for addons/frameworks)

223

* @param path - Path to the array field

224

* @param value - Name of entry to remove

225

*/

226

removeEntryFromArray(path: string[], value: string): void;

227

```

228

229

**Usage Examples:**

230

231

```typescript

232

// Add a new addon

233

config.appendValueToArray(['addons'], '@storybook/addon-docs');

234

235

// Remove an addon

236

config.removeEntryFromArray(['addons'], '@storybook/addon-actions');

237

238

// Add story pattern

239

config.appendValueToArray(['stories'], '../components/**/*.stories.ts');

240

```

241

242

### Import Management

243

244

Methods for managing import statements in configuration files.

245

246

```typescript { .api }

247

/**

248

* Add or update ES6 import statement

249

* @param importSpecifier - Import specifiers (string for default, array for named, object for namespace)

250

* @param fromImport - Module to import from

251

*/

252

setImport(

253

importSpecifier: string[] | string | { namespace: string } | null,

254

fromImport: string

255

): void;

256

257

/**

258

* Add or update CommonJS require statement

259

* @param importSpecifier - Import specifiers (string for default, array for destructured)

260

* @param fromImport - Module to require from

261

*/

262

setRequireImport(importSpecifier: string[] | string, fromImport: string): void;

263

```

264

265

**Usage Examples:**

266

267

```typescript

268

// Add ES6 imports

269

config.setImport(['StorybookConfig'], '@storybook/types');

270

config.setImport('path', 'path');

271

config.setImport({ namespace: 'fs' }, 'fs');

272

273

// Add CommonJS requires

274

config.setRequireImport(['join'], 'path');

275

config.setRequireImport('express', 'express');

276

```

277

278

### Utility Functions

279

280

Helper functions for configuration analysis.

281

282

```typescript { .api }

283

/**

284

* Check if preview configuration uses CSF factory pattern

285

* @param previewConfig - Parsed preview configuration

286

* @returns True if CSF factory pattern is detected

287

*/

288

function isCsfFactoryPreview(previewConfig: ConfigFile): boolean;

289

290

/**

291

* Convert JavaScript value to AST node with proper quote style

292

* @param value - Value to convert

293

* @returns AST expression node

294

*/

295

valueToNode(value: any): t.Expression | undefined;

296

```

297

298

## Configuration Patterns

299

300

### Main Configuration

301

302

Typical patterns for working with .storybook/main.js:

303

304

```typescript

305

import { readConfig, writeConfig } from "@storybook/csf-tools";

306

307

const config = await readConfig('.storybook/main.js');

308

309

// Modify stories glob patterns

310

const currentStories = config.getFieldValue(['stories']);

311

config.setFieldValue(['stories'], [

312

...currentStories,

313

'../components/**/*.stories.@(js|ts|jsx|tsx)'

314

]);

315

316

// Add an addon

317

config.appendValueToArray(['addons'], {

318

name: '@storybook/addon-docs',

319

options: { transcludeMarkdown: true }

320

});

321

322

// Set framework

323

config.setFieldValue(['framework'], {

324

name: '@storybook/react-vite',

325

options: { builder: { viteConfigPath: './vite.config.ts' } }

326

});

327

328

await writeConfig(config);

329

```

330

331

### Preview Configuration

332

333

Working with .storybook/preview.js:

334

335

```typescript

336

const preview = await readConfig('.storybook/preview.js');

337

338

// Set global parameters

339

preview.setFieldValue(['parameters', 'actions'], { argTypesRegex: '^on[A-Z].*' });

340

preview.setFieldValue(['parameters', 'docs'], {

341

page: null,

342

source: { type: 'code' }

343

});

344

345

// Add decorators

346

preview.appendValueToArray(['decorators'], 'withThemeProvider');

347

348

await writeConfig(preview);

349

```