or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

auto-detection.mdcli-interface.mdconfiguration.mdcss-minification.mdhtml-minification.mdimage-processing.mdindex.mdjavascript-minification.md

configuration.mddocs/

0

# Configuration System

1

2

Flexible configuration management supporting .minify.json files with directory traversal for CLI usage and direct options passing for programmatic usage.

3

4

## Capabilities

5

6

### .minify.json Configuration Files

7

8

The CLI automatically reads .minify.json configuration files from the current directory or parent directories. For programmatic usage, pass options directly to minify functions.

9

10

```javascript { .api }

11

interface MinifyConfiguration {

12

js?: JSConfiguration;

13

css?: CSSConfiguration;

14

html?: HTMLConfiguration;

15

img?: ImageConfiguration;

16

}

17

18

interface JSConfiguration {

19

type?: 'putout' | 'terser' | 'esbuild' | 'swc';

20

putout?: PutoutOptions;

21

terser?: TerserOptions;

22

esbuild?: ESBuildOptions;

23

swc?: SWCOptions;

24

}

25

26

interface CSSConfiguration {

27

type?: 'lightningcss' | 'clean-css';

28

'clean-css'?: CleanCSSOptions;

29

}

30

31

interface HTMLConfiguration extends HTMLMinifierOptions {}

32

33

interface ImageConfiguration {

34

maxSize?: number;

35

}

36

```

37

38

**Usage Examples:**

39

40

```javascript

41

import { minify } from "minify";

42

43

// Programmatic usage - pass options directly

44

const options = {

45

js: { type: 'terser', terser: { mangle: true } },

46

css: { type: 'clean-css' },

47

html: { removeComments: true }

48

};

49

50

const minified = await minify.js(source, options);

51

52

// CLI usage automatically loads .minify.json files

53

// No programmatic import needed for configuration files

54

```

55

56

## Configuration File Format

57

58

### .minify.json Structure

59

60

The configuration file uses JSON format with sections for each minifier type:

61

62

```json { .api }

63

{

64

"js": {

65

"type": "putout",

66

"putout": {

67

"quote": "'",

68

"mangle": true,

69

"mangleClassNames": true,

70

"removeUnusedVariables": true,

71

"removeConsole": false,

72

"removeUselessSpread": true

73

},

74

"terser": {

75

"mangle": true,

76

"compress": {

77

"drop_console": true

78

}

79

},

80

"esbuild": {

81

"minifyWhitespace": true,

82

"minifyIdentifiers": true,

83

"minifySyntax": true

84

},

85

"swc": {

86

"mangle": true,

87

"module": true

88

}

89

},

90

"css": {

91

"type": "clean-css",

92

"clean-css": {

93

"level": 2,

94

"compatibility": "*"

95

}

96

},

97

"html": {

98

"removeComments": true,

99

"removeCommentsFromCDATA": true,

100

"removeCDATASectionsFromCDATA": true,

101

"collapseWhitespace": true,

102

"collapseBooleanAttributes": true,

103

"removeAttributeQuotes": true,

104

"removeRedundantAttributes": true,

105

"useShortDoctype": true,

106

"removeEmptyAttributes": true,

107

"removeEmptyElements": false,

108

"removeOptionalTags": true,

109

"removeScriptTypeAttributes": true,

110

"removeStyleLinkTypeAttributes": true,

111

"minifyJS": true,

112

"minifyCSS": true

113

},

114

"img": {

115

"maxSize": 4096

116

}

117

}

118

```

119

120

## Directory Traversal

121

122

### Configuration File Discovery

123

124

The system walks up parent directories to find .minify.json files:

125

126

```javascript { .api }

127

interface DirectoryTraversal {

128

startDirectory: string; // Current working directory

129

searchPattern: string; // ".minify.json" filename

130

traversalOrder: string[]; // Directories checked in order

131

stopCondition: string; // Root directory or first file found

132

}

133

134

// Example traversal path:

135

// /project/src/components/ → /project/src/components/.minify.json

136

// /project/src/ → /project/src/.minify.json

137

// /project/ → /project/.minify.json

138

// / → /.minify.json

139

```

140

141

**Directory Traversal Examples:**

142

143

```javascript

144

// Project structure:

145

// /project/

146

// ├── .minify.json ← Root configuration

147

// ├── src/

148

// │ ├── .minify.json ← Source-specific overrides

149

// │ └── components/

150

// │ └── Button.js ← Uses src/.minify.json

151

152

// CLI working from /project/src/components/

153

minify Button.js

154

// Uses: /project/src/.minify.json

155

156

// CLI working from /project/

157

minify src/components/Button.js

158

// Uses: /project/.minify.json

159

160

// No configuration file found - uses defaults

161

// CLI working from /tmp/

162

minify /some/file.js

163

// Uses: built-in defaults

164

```

165

166

## Configuration Sections

167

168

### JavaScript Configuration

169

170

Configure JavaScript minifiers with type selection and options:

171

172

```json { .api }

173

{

174

"js": {

175

"type": "putout",

176

"putout": {

177

"quote": "'",

178

"mangle": true,

179

"mangleClassNames": true,

180

"removeUnusedVariables": true,

181

"removeConsole": false,

182

"removeUselessSpread": true

183

}

184

}

185

}

186

```

187

188

**JavaScript Configuration Examples:**

189

190

```json

191

// Putout configuration (default)

192

{

193

"js": {

194

"type": "putout",

195

"putout": {

196

"mangle": true,

197

"removeUnusedVariables": false,

198

"quote": "'"

199

}

200

}

201

}

202

203

// Terser configuration

204

{

205

"js": {

206

"type": "terser",

207

"terser": {

208

"mangle": {

209

"toplevel": true

210

},

211

"compress": {

212

"drop_console": true,

213

"drop_debugger": true,

214

"pure_funcs": ["console.log"]

215

}

216

}

217

}

218

}

219

220

// ESBuild configuration

221

{

222

"js": {

223

"type": "esbuild",

224

"esbuild": {

225

"minifyWhitespace": true,

226

"minifyIdentifiers": true,

227

"minifySyntax": true,

228

"target": ["es2020"]

229

}

230

}

231

}

232

233

// SWC configuration

234

{

235

"js": {

236

"type": "swc",

237

"swc": {

238

"mangle": true,

239

"module": true,

240

"compress": {

241

"unused": true

242

}

243

}

244

}

245

}

246

```

247

248

### CSS Configuration

249

250

Configure CSS minifiers with backend selection and optimization levels:

251

252

```json { .api }

253

{

254

"css": {

255

"type": "clean-css",

256

"clean-css": {

257

"level": {

258

"1": {

259

"specialComments": 0,

260

"removeWhitespace": true

261

},

262

"2": {

263

"mergeAdjacentRules": true,

264

"removeEmpty": true,

265

"removeDuplicateRules": true

266

}

267

},

268

"compatibility": {

269

"properties": {

270

"colors": false,

271

"ieFilters": true

272

}

273

}

274

}

275

}

276

}

277

```

278

279

**CSS Configuration Examples:**

280

281

```json

282

// LightningCSS (default - minimal configuration)

283

{

284

"css": {

285

"type": "lightningcss"

286

}

287

}

288

289

// Clean-CSS with optimization levels

290

{

291

"css": {

292

"type": "clean-css",

293

"clean-css": {

294

"level": 2,

295

"compatibility": "*",

296

"format": "beautify",

297

"sourceMap": true

298

}

299

}

300

}

301

302

// Clean-CSS with detailed options

303

{

304

"css": {

305

"type": "clean-css",

306

"clean-css": {

307

"level": {

308

"1": {

309

"cleanupCharsets": true,

310

"normalizeUrls": true,

311

"optimizeBackground": true,

312

"optimizeBorderRadius": true,

313

"optimizeFilter": true,

314

"optimizeFont": true,

315

"removeEmpty": true,

316

"removeWhitespace": true,

317

"specialComments": "all"

318

},

319

"2": {

320

"mergeAdjacentRules": true,

321

"mergeIntoShorthands": true,

322

"mergeMedia": true,

323

"removeDuplicateRules": true,

324

"removeUnusedAtRules": false

325

}

326

}

327

}

328

}

329

}

330

```

331

332

### HTML Configuration

333

334

Configure HTML minification with comprehensive optimization settings:

335

336

```json { .api }

337

{

338

"html": {

339

"removeComments": true,

340

"removeCommentsFromCDATA": true,

341

"removeCDATASectionsFromCDATA": true,

342

"collapseWhitespace": true,

343

"collapseBooleanAttributes": true,

344

"removeAttributeQuotes": true,

345

"removeRedundantAttributes": true,

346

"useShortDoctype": true,

347

"removeEmptyAttributes": true,

348

"removeEmptyElements": false,

349

"removeOptionalTags": true,

350

"removeScriptTypeAttributes": true,

351

"removeStyleLinkTypeAttributes": true,

352

"minifyJS": true,

353

"minifyCSS": true

354

}

355

}

356

```

357

358

**HTML Configuration Examples:**

359

360

```json

361

// Conservative HTML minification

362

{

363

"html": {

364

"removeComments": false,

365

"collapseWhitespace": true,

366

"removeEmptyElements": false,

367

"removeOptionalTags": false,

368

"minifyJS": false,

369

"minifyCSS": false

370

}

371

}

372

373

// Aggressive HTML minification

374

{

375

"html": {

376

"removeComments": true,

377

"collapseWhitespace": true,

378

"removeAttributeQuotes": true,

379

"removeRedundantAttributes": true,

380

"removeEmptyAttributes": true,

381

"removeOptionalTags": true,

382

"minifyJS": true,

383

"minifyCSS": true,

384

"useShortDoctype": true

385

}

386

}

387

388

// Template-friendly configuration

389

{

390

"html": {

391

"collapseWhitespace": true,

392

"removeComments": false,

393

"removeEmptyElements": false,

394

"ignoreCustomFragments": [

395

"<%[\\s\\S]*?%>",

396

"<\\?[\\s\\S]*?\\?>"

397

]

398

}

399

}

400

```

401

402

### Image Configuration

403

404

Configure image processing and base64 inlining thresholds:

405

406

```json { .api }

407

{

408

"img": {

409

"maxSize": 102400

410

}

411

}

412

```

413

414

**Image Configuration Examples:**

415

416

```json

417

// Conservative image inlining (small files only)

418

{

419

"img": {

420

"maxSize": 10000

421

}

422

}

423

424

// Aggressive image inlining

425

{

426

"img": {

427

"maxSize": 500000

428

}

429

}

430

431

// Disable image inlining

432

{

433

"img": {

434

"maxSize": 0

435

}

436

}

437

438

// Default behavior (100KB threshold)

439

{

440

"img": {

441

"maxSize": 102400

442

}

443

}

444

```

445

446

## Configuration Hierarchy

447

448

### Precedence Rules

449

450

Configuration sources are applied in order of precedence:

451

452

```javascript { .api }

453

interface ConfigurationPrecedence {

454

1: 'runtime-options'; // Highest: Options passed to minify functions

455

2: 'nearest-config-file'; // .minify.json in current/nearest parent directory

456

3: 'default-settings'; // Lowest: Built-in default configurations

457

}

458

459

// Example precedence resolution for programmatic usage:

460

const runtimeOptions = { js: { type: 'terser' } }; // Passed to function

461

462

const finalConfig = {

463

...builtInDefaults,

464

...runtimeOptions // Takes precedence

465

};

466

```

467

468

**Hierarchy Examples:**

469

470

```javascript

471

// Project with nested configuration

472

// /project/.minify.json:

473

{

474

"js": { "type": "putout" },

475

"css": { "type": "clean-css" }

476

}

477

478

// /project/src/.minify.json:

479

{

480

"js": { "type": "terser" } // Overrides parent

481

}

482

483

// CLI working from /project/src/ uses nearest config:

484

minify app.js

485

// Uses: { js: { type: "terser" }, css: { type: "clean-css" } }

486

487

// Programmatic usage ignores config files:

488

const result = await minify.js(source, {

489

js: { type: 'esbuild' } // Only uses passed options

490

});

491

```

492

493

## Error Handling

494

495

### Configuration Error Management

496

497

Robust error handling for configuration file issues:

498

499

```javascript { .api }

500

interface ConfigurationErrors {

501

fileNotFound: 'cli-uses-defaults'; // CLI continues with defaults

502

invalidJSON: 'cli-throws-parse-error'; // JSON syntax errors in CLI

503

filePermissions: 'cli-throws-access-error'; // File access denied in CLI

504

malformedOptions: 'validates-at-usage'; // Validation during minification

505

}

506

```

507

508

**Error Handling Examples:**

509

510

```bash

511

# Missing configuration file (CLI uses defaults)

512

minify app.js

513

# Uses built-in defaults, no error

514

515

# Invalid JSON syntax in .minify.json

516

# { "js": { type: "invalid" } // Missing closing brace

517

minify app.js

518

# CLI Error: JSON parse error in .minify.json

519

520

# File permission error

521

# .minify.json exists but is not readable

522

minify app.js

523

# CLI Error: EACCES - cannot read .minify.json

524

```

525

526

```javascript

527

// Invalid configuration options (caught during programmatic usage)

528

const invalidConfig = { js: { type: 'nonexistent-minifier' } };

529

try {

530

const result = await minify.js(source, invalidConfig);

531

} catch (error) {

532

console.log(error.message); // Invalid minifier type error

533

}

534

```

535

536

## Testing and Development

537

538

### Configuration Usage Patterns

539

540

Different approaches for various use cases:

541

542

```javascript { .api }

543

interface UsagePatterns {

544

programmatic: 'pass-options-directly';

545

cli: 'use-minify-json-files';

546

testing: 'pass-options-directly';

547

environment: 'conditional-configuration';

548

}

549

550

// Production vs Development example

551

const getConfig = (environment) => ({

552

js: {

553

type: environment === 'production' ? 'terser' : 'putout',

554

[environment === 'production' ? 'terser' : 'putout']: {

555

mangle: environment === 'production',

556

removeConsole: environment === 'production'

557

}

558

}

559

});

560

```

561

562

**Testing Integration Examples:**

563

564

```javascript

565

// Test configuration by passing options directly

566

import { minify } from 'minify';

567

568

describe('Configuration System', () => {

569

test('should use custom JS configuration', async () => {

570

const options = { js: { type: 'esbuild' } };

571

const result = await minify.js('function test() {}', options);

572

expect(result).toBeTruthy();

573

});

574

575

test('should use custom CSS configuration', async () => {

576

const options = { css: { type: 'clean-css' } };

577

const result = await minify.css('body { color: red; }', options);

578

expect(result).toBeTruthy();

579

});

580

});

581

582

// Development environment - different configs for dev vs prod

583

const isDev = process.env.NODE_ENV === 'development';

584

const devConfig = {

585

js: {

586

type: 'putout',

587

putout: { removeConsole: false } // Keep console in dev

588

}

589

};

590

const prodConfig = {

591

js: {

592

type: 'terser',

593

terser: { compress: { drop_console: true } }

594

}

595

};

596

597

const config = isDev ? devConfig : prodConfig;

598

const result = await minify.js(source, config);

599

```