0
# Environment and Runtime
1
2
JSDoc's environment system provides access to runtime information, configuration data, command-line options, and execution state throughout the documentation generation process.
3
4
## Capabilities
5
6
### Environment Object
7
8
Global environment object containing all runtime state and configuration.
9
10
```javascript { .api }
11
const env = {
12
/** Execution timing information */
13
run: {
14
/** When JSDoc execution started */
15
start: Date;
16
/** When JSDoc execution finished (null during execution) */
17
finish: Date | null;
18
};
19
20
/** Original command-line arguments array */
21
args: string[];
22
23
/** Loaded and merged configuration object */
24
conf: ConfigObject;
25
26
/** Absolute path to JSDoc installation directory */
27
dirname: string;
28
29
/** Working directory when JSDoc was started */
30
pwd: string;
31
32
/** Parsed command-line options */
33
opts: CommandLineOptions;
34
35
/** Array of source file paths to process */
36
sourceFiles: string[];
37
38
/** JSDoc version information */
39
version: {
40
/** Version number string */
41
number: string;
42
/** Revision date string */
43
revision: string;
44
};
45
};
46
```
47
48
### Command-Line Options Interface
49
50
Structure of parsed command-line options available in `env.opts`.
51
52
```javascript { .api }
53
interface CommandLineOptions {
54
/** Output destination directory */
55
destination?: string;
56
57
/** File encoding for reading source files */
58
encoding?: string;
59
60
/** Path to configuration file */
61
configure?: string;
62
63
/** Path to template directory */
64
template?: string;
65
66
/** Include private members in documentation */
67
private?: boolean;
68
69
/** Path to README file */
70
readme?: string;
71
72
/** Path to package.json file */
73
package?: string;
74
75
/** Enable debug logging */
76
debug?: boolean;
77
78
/** Enable verbose logging */
79
verbose?: boolean;
80
81
/** Recursively scan directories */
82
recurse?: boolean;
83
84
/** Path to tutorials directory */
85
tutorials?: string;
86
87
/** Access levels to include */
88
access?: string | string[];
89
90
/** Treat warnings as errors */
91
pedantic?: boolean;
92
93
/** Display help and exit */
94
help?: boolean;
95
96
/** Display version and exit */
97
version?: boolean;
98
99
/** Run test suite */
100
test?: boolean;
101
102
/** Dump doclet internals to console */
103
explain?: boolean;
104
105
/** Custom query parameters object */
106
query?: object;
107
108
/** Positional arguments (source files/directories) */
109
_?: string[];
110
}
111
```
112
113
## Environment Access
114
115
### Getting Environment Information
116
117
```javascript
118
const env = require('jsdoc/env');
119
120
// Check execution state
121
console.log('JSDoc started at:', env.run.start);
122
console.log('Working directory:', env.pwd);
123
console.log('JSDoc version:', env.version.number);
124
125
// Access configuration
126
console.log('Output destination:', env.opts.destination);
127
console.log('Debug mode:', env.opts.debug);
128
console.log('Plugins loaded:', env.conf.plugins);
129
130
// Check source files
131
console.log('Processing files:', env.sourceFiles);
132
```
133
134
### Environment State Checking
135
136
```javascript
137
// Check if in debug mode
138
if (env.opts.debug) {
139
console.log('Debug information enabled');
140
}
141
142
// Check if private members should be included
143
if (env.opts.private) {
144
console.log('Including private members');
145
}
146
147
// Check template configuration
148
if (env.conf.templates && env.conf.templates.cleverLinks) {
149
console.log('Clever links enabled');
150
}
151
152
// Validate required options
153
if (!env.opts.destination) {
154
console.warn('No destination specified, using default');
155
}
156
```
157
158
## Runtime Information
159
160
### Timing Information
161
162
```javascript
163
// Access timing information
164
const startTime = env.run.start;
165
console.log('JSDoc started at:', startTime.toISOString());
166
167
// Calculate duration (if finished)
168
if (env.run.finish) {
169
const duration = env.run.finish.getTime() - env.run.start.getTime();
170
console.log(`Execution took ${duration}ms`);
171
}
172
```
173
174
### Version Information
175
176
```javascript
177
// Get version details
178
const versionInfo = env.version;
179
console.log(`JSDoc ${versionInfo.number}`);
180
console.log(`Revision: ${versionInfo.revision}`);
181
182
// Version string formatting
183
const versionString = `JSDoc ${versionInfo.number} (${versionInfo.revision})`;
184
```
185
186
### Path Information
187
188
```javascript
189
// Get path information
190
const jsdocDir = env.dirname;
191
const workingDir = env.pwd;
192
193
console.log('JSDoc installed at:', jsdocDir);
194
console.log('Working directory:', workingDir);
195
196
// Resolve relative paths
197
const path = require('path');
198
const configPath = path.resolve(workingDir, env.opts.configure || 'jsdoc.conf.json');
199
```
200
201
## Configuration Access
202
203
### Reading Configuration
204
205
```javascript
206
// Access main configuration sections
207
const sourceConfig = env.conf.source;
208
const pluginList = env.conf.plugins;
209
const templateConfig = env.conf.templates;
210
211
// Check source patterns
212
console.log('Include pattern:', sourceConfig.includePattern);
213
console.log('Exclude pattern:', sourceConfig.excludePattern);
214
215
// Check loaded plugins
216
pluginList.forEach(plugin => {
217
console.log('Plugin loaded:', plugin);
218
});
219
```
220
221
### Command-Line Option Access
222
223
```javascript
224
// Access all command-line options
225
const opts = env.opts;
226
227
// Check boolean flags
228
const flags = {
229
debug: opts.debug || false,
230
verbose: opts.verbose || false,
231
private: opts.private || false,
232
recurse: opts.recurse || false,
233
pedantic: opts.pedantic || false
234
};
235
236
// Get paths
237
const paths = {
238
destination: opts.destination || './out/',
239
template: opts.template || 'templates/default',
240
readme: opts.readme,
241
package: opts.package,
242
tutorials: opts.tutorials
243
};
244
245
// Get source files from positional arguments
246
const sourceFiles = opts._ || [];
247
```
248
249
## Environment Modification
250
251
### Setting Environment Values
252
253
```javascript
254
// Set configuration values (typically done during initialization)
255
env.opts.destination = './custom-docs/';
256
env.opts.debug = true;
257
258
// Add source files
259
env.sourceFiles = ['src/index.js', 'src/utils.js'];
260
261
// Set version information
262
env.version = {
263
number: '4.0.4',
264
revision: 'Wed Oct 19 2023 12:00:00 GMT+0000 (UTC)'
265
};
266
```
267
268
### Environment Validation
269
270
```javascript
271
function validateEnvironment() {
272
const issues = [];
273
274
// Check required paths exist
275
const fs = require('fs');
276
277
if (env.opts.readme && !fs.existsSync(env.opts.readme)) {
278
issues.push(`README file not found: ${env.opts.readme}`);
279
}
280
281
if (env.opts.package && !fs.existsSync(env.opts.package)) {
282
issues.push(`Package file not found: ${env.opts.package}`);
283
}
284
285
// Check source files
286
if (!env.sourceFiles || env.sourceFiles.length === 0) {
287
issues.push('No source files specified');
288
}
289
290
// Validate configuration
291
if (!env.conf) {
292
issues.push('No configuration loaded');
293
}
294
295
return issues;
296
}
297
298
// Usage
299
const issues = validateEnvironment();
300
if (issues.length > 0) {
301
console.error('Environment issues:', issues);
302
}
303
```
304
305
## Global Environment Access
306
307
### Deprecated Global Access
308
309
JSDoc provides deprecated global access to environment (for backward compatibility):
310
311
```javascript
312
// Deprecated: global.env (use require('jsdoc/env') instead)
313
global.env = (() => require('jsdoc/env'))();
314
315
// Deprecated: global.app (use require('jsdoc/app') instead)
316
global.app = (() => require('jsdoc/app'))();
317
318
// Access patterns (deprecated)
319
if (global.env.opts.debug) {
320
// Debug functionality
321
}
322
```
323
324
### Modern Environment Access
325
326
```javascript
327
// Preferred: require the env module
328
const env = require('jsdoc/env');
329
330
// Access environment information
331
const isDebug = env.opts.debug;
332
const outputDir = env.opts.destination;
333
334
// Use in plugin development
335
exports.handlers = {
336
parseBegin: function(e) {
337
if (env.opts.verbose) {
338
console.log('Starting parse of:', e.sourcefiles.length, 'files');
339
}
340
}
341
};
342
```
343
344
## Usage Examples
345
346
### Environment-Aware Plugin
347
348
```javascript
349
// environment-plugin.js
350
const env = require('jsdoc/env');
351
352
exports.handlers = {
353
parseBegin: function(e) {
354
// Log based on environment settings
355
if (env.opts.verbose) {
356
console.log(`JSDoc ${env.version.number} starting parse`);
357
console.log(`Output destination: ${env.opts.destination}`);
358
console.log(`Processing ${e.sourcefiles.length} files`);
359
}
360
361
// Debug information
362
if (env.opts.debug) {
363
console.log('Environment state:', {
364
pwd: env.pwd,
365
dirname: env.dirname,
366
sourceFiles: env.sourceFiles,
367
plugins: env.conf.plugins
368
});
369
}
370
},
371
372
parseComplete: function(e) {
373
if (env.opts.verbose) {
374
const duration = Date.now() - env.run.start.getTime();
375
console.log(`Parse completed in ${duration}ms`);
376
console.log(`Generated ${e.doclets.length} doclets`);
377
}
378
}
379
};
380
```
381
382
### Configuration-Based Processing
383
384
```javascript
385
// config-processor.js
386
const env = require('jsdoc/env');
387
388
function processBasedOnConfig() {
389
const conf = env.conf;
390
391
// Markdown processing based on plugin
392
const hasMarkdown = conf.plugins.includes('plugins/markdown');
393
394
// Template-specific processing
395
const templateConfig = conf.templates || {};
396
const useCleverLinks = templateConfig.cleverLinks;
397
398
// Source filtering based on patterns
399
const includePattern = new RegExp(conf.source.includePattern);
400
const excludePattern = conf.source.excludePattern ?
401
new RegExp(conf.source.excludePattern) : null;
402
403
return {
404
hasMarkdown,
405
useCleverLinks,
406
includePattern,
407
excludePattern
408
};
409
}
410
411
// Usage in template
412
exports.publish = function(data, opts) {
413
const config = processBasedOnConfig();
414
415
if (config.hasMarkdown) {
416
// Process markdown in descriptions
417
}
418
419
if (config.useCleverLinks) {
420
// Generate intelligent link text
421
}
422
};
423
```
424
425
### Runtime State Management
426
427
```javascript
428
// state-manager.js
429
const env = require('jsdoc/env');
430
431
class RuntimeState {
432
constructor() {
433
this.startTime = env.run.start;
434
this.isDebug = env.opts.debug;
435
this.isVerbose = env.opts.verbose;
436
}
437
438
logTiming(message) {
439
if (this.isVerbose) {
440
const elapsed = Date.now() - this.startTime.getTime();
441
console.log(`[${elapsed}ms] ${message}`);
442
}
443
}
444
445
debugLog(message, data) {
446
if (this.isDebug) {
447
console.log(`[DEBUG] ${message}`, data || '');
448
}
449
}
450
451
getConfig(key) {
452
return key ? env.conf[key] : env.conf;
453
}
454
455
getOption(key) {
456
return key ? env.opts[key] : env.opts;
457
}
458
}
459
460
module.exports = new RuntimeState();
461
```
462
463
### Environment Information Display
464
465
```javascript
466
// env-info.js
467
const env = require('jsdoc/env');
468
469
function displayEnvironmentInfo() {
470
console.log('\n=== JSDoc Environment Information ===');
471
console.log(`Version: ${env.version.number}`);
472
console.log(`Revision: ${env.version.revision}`);
473
console.log(`Started: ${env.run.start.toISOString()}`);
474
console.log(`Working Directory: ${env.pwd}`);
475
console.log(`JSDoc Directory: ${env.dirname}`);
476
477
console.log('\n--- Configuration ---');
478
console.log(`Plugins: ${env.conf.plugins.join(', ') || 'none'}`);
479
console.log(`Include Pattern: ${env.conf.source.includePattern}`);
480
console.log(`Exclude Pattern: ${env.conf.source.excludePattern || 'none'}`);
481
482
console.log('\n--- Command Line Options ---');
483
console.log(`Destination: ${env.opts.destination || 'default'}`);
484
console.log(`Template: ${env.opts.template || 'default'}`);
485
console.log(`Debug: ${env.opts.debug || false}`);
486
console.log(`Verbose: ${env.opts.verbose || false}`);
487
console.log(`Private: ${env.opts.private || false}`);
488
console.log(`Recurse: ${env.opts.recurse || false}`);
489
490
console.log('\n--- Source Files ---');
491
console.log(`Count: ${env.sourceFiles.length}`);
492
if (env.opts.verbose && env.sourceFiles.length > 0) {
493
env.sourceFiles.forEach(file => console.log(` ${file}`));
494
}
495
console.log('=====================================\n');
496
}
497
498
// Usage
499
if (env.opts.debug || env.opts.verbose) {
500
displayEnvironmentInfo();
501
}
502
```
503
504
## Integration Patterns
505
506
### Plugin Environment Integration
507
508
```javascript
509
// Plugin that adapts to environment
510
exports.handlers = {
511
parseBegin: function(e) {
512
// Adapt behavior based on environment
513
this.isProduction = !env.opts.debug && !env.opts.verbose;
514
this.outputDir = env.opts.destination;
515
this.templatePath = env.opts.template;
516
},
517
518
newDoclet: function(e) {
519
// Production vs development processing
520
if (this.isProduction) {
521
// Minimal processing for production
522
if (e.doclet.kind === 'function' && !e.doclet.description) {
523
e.doclet.undocumented = true;
524
}
525
} else {
526
// Enhanced processing for development
527
if (!e.doclet.description) {
528
console.warn(`Missing description: ${e.doclet.longname}`);
529
}
530
}
531
}
532
};
533
```
534
535
### Template Environment Integration
536
537
```javascript
538
// Template that uses environment information
539
exports.publish = function(data, opts) {
540
const env = require('jsdoc/env');
541
542
// Template configuration based on environment
543
const templateConfig = {
544
debug: env.opts.debug,
545
verbose: env.opts.verbose,
546
version: env.version.number,
547
generatedAt: new Date().toISOString(),
548
sourceCount: env.sourceFiles.length
549
};
550
551
// Pass environment info to templates
552
const commonData = {
553
env: templateConfig,
554
packageInfo: opts.package,
555
hasReadme: !!opts.readme
556
};
557
558
// Generate pages with environment context
559
generateIndexPage(data, commonData);
560
generateClassPages(data, commonData);
561
};
562
```