Static analysis tool for JavaScript that detects errors and potential problems in code
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Pluggable output formatters for different use cases including default, unix, checkstyle, and XML formats. JSHint's reporting system allows customization of how linting results are displayed and processed.
Standard interface that all JSHint reporters must implement.
/**
* Reporter function interface for formatting JSHint output
* @param results - Array of linting result objects containing file and error info
* @param data - Array of detailed analysis data objects from JSHINT.data()
* @param opts - Reporter options object (verbose, filename, etc.)
*/
function reporter(results, data, opts) {
// results: Array of result objects
// data: Array of JSHINT.data() objects
// opts: Reporter options object
}
// Result Object Structure
{
file: string, // File path
error: { // Error details
line: number, // Line number
character: number, // Character position
reason: string, // Error message
code: string, // Error code
evidence: string // Source code line (optional)
}
}
// Data Object Structure (from JSHINT.data())
{
functions: Array, // Function analysis data
options: Object, // Options used
errors: Array, // Error objects
implieds: Array, // Implied globals
globals: Array, // Used/defined globals
unused: Array, // Unused variables
member: Object, // Member usage data
json: boolean // JSON mode flag
}
// Options Object Structure
{
verbose: boolean, // Show error codes
filename: string // Filename for stdin input
}Usage Examples:
// Custom reporter implementation
const myReporter = {
reporter: function(results, data, opts) {
// Process results
results.forEach(result => {
if (result.error) {
console.log(`Error in ${result.file}:`);
console.log(` Line ${result.error.line}: ${result.error.reason}`);
if (opts.verbose) {
console.log(` Code: ${result.error.code}`);
}
}
});
// Process additional data if needed
data.forEach(fileData => {
if (fileData.unused && fileData.unused.length > 0) {
console.log('Unused variables:', fileData.unused);
}
});
}
};
// Use with CLI
// jshint --reporter ./my-reporter.js file.jsJSHint includes several built-in reporters for different output formats and use cases.
/**
* Default reporter - Human-readable format with colors
* Located at: src/reporters/default.js
*/
interface DefaultReporter {
reporter(results, data, opts): void;
}
/**
* Unix reporter - Standard unix tool output format
* Format: filename:line:column: message
* Located at: src/reporters/unix.js
*/
interface UnixReporter {
reporter(results, data, opts): void;
}
/**
* Checkstyle reporter - XML format for CI tools
* Located at: src/reporters/checkstyle.js
*/
interface CheckstyleReporter {
reporter(results, data, opts): void;
}
/**
* JSLint XML reporter - JSLint-compatible XML output
* Located at: src/reporters/jslint_xml.js
*/
interface JSLintXMLReporter {
reporter(results, data, opts): void;
}
/**
* Non-error reporter - Shows additional JSHint data beyond errors
* Located at: src/reporters/non_error.js
*/
interface NonErrorReporter {
reporter(results, data, opts): void;
}Usage Examples:
# Default reporter (human-readable)
jshint app.js
# Unix format (great for grep, editors)
jshint --reporter unix app.js
# XML format for CI systems
jshint --reporter checkstyle app.js > checkstyle.xml
# JSLint-compatible XML
jshint --reporter jslint_xml app.js
# Show additional analysis data
jshint --show-non-errors app.jsHuman-readable output format with optional colors and detailed error information.
Example Output:
app.js: line 12, col 25, Missing semicolon. (W033)
app.js: line 15, col 10, 'unusedVar' is defined but never used. (W098)
2 errorsWith verbose mode:
jshint --verbose app.jsapp.js: line 12, col 25, Missing semicolon. (W033)
app.js: line 15, col 10, 'unusedVar' is defined but never used. (W098)
2 errorsStandard Unix tool output format ideal for integration with editors, grep, and other command-line tools.
Format: filename:line:column: message
Example Output:
app.js:12:25: Missing semicolon.
app.js:15:10: 'unusedVar' is defined but never used.Usage with editors:
# Vim quickfix
jshint --reporter unix *.js | vim -q -
# Emacs compilation mode
jshint --reporter unix src/XML format compatible with checkstyle and many CI/CD systems.
Example Output:
<?xml version="1.0" encoding="utf-8"?>
<checkstyle version="4.3">
<file name="app.js">
<error line="12" column="25" severity="error" message="Missing semicolon." source="jshint.W033" />
<error line="15" column="10" severity="error" message="'unusedVar' is defined but never used." source="jshint.W098" />
</file>
</checkstyle>CI Integration Examples:
# Jenkins with Checkstyle plugin
jshint --reporter checkstyle src/ > checkstyle-jshint.xml
# SonarQube integration
jshint --reporter checkstyle --config .jshintrc src/ > jshint-report.xmlJSLint-compatible XML format for tools that expect JSLint output.
Example Output:
<?xml version="1.0" encoding="UTF-8" ?>
<jslint>
<file name="app.js">
<issue line="12" char="25" reason="Missing semicolon." evidence=" var x = 1" />
<issue line="15" char="10" reason="'unusedVar' is defined but never used." evidence=" var unusedVar = 42;" />
</file>
</jslint>Shows additional JSHint analysis data beyond just errors, including function information, globals, and unused variables.
Example Output:
app.js:
Functions: 3
Globals: console, require, module
Unused variables: unusedVar (Line 15)
Implied globals: (none)Usage:
jshint --show-non-errors app.jsCreating custom reporters for specific needs and integrations.
/**
* Custom reporter template
* Export an object with a reporter function
*/
interface CustomReporter {
reporter(results, data, opts): void;
}JSON Reporter Example:
// json-reporter.js
module.exports = {
reporter: function(results, data, opts) {
const output = {
timestamp: new Date().toISOString(),
files: results.reduce((acc, result) => {
if (!acc[result.file]) {
acc[result.file] = {
errors: [],
warnings: []
};
}
if (result.error) {
const error = {
line: result.error.line,
column: result.error.character,
message: result.error.reason,
code: result.error.code,
severity: result.error.code.startsWith('E') ? 'error' : 'warning'
};
if (error.severity === 'error') {
acc[result.file].errors.push(error);
} else {
acc[result.file].warnings.push(error);
}
}
return acc;
}, {}),
summary: {
totalFiles: Object.keys(results.reduce((acc, r) => {
acc[r.file] = true;
return acc;
}, {})).length,
totalErrors: results.filter(r => r.error && r.error.code.startsWith('E')).length,
totalWarnings: results.filter(r => r.error && r.error.code.startsWith('W')).length
}
};
console.log(JSON.stringify(output, null, 2));
}
};Usage:
jshint --reporter ./json-reporter.js src/ > report.jsonSlack Reporter Example:
// slack-reporter.js
const https = require('https');
module.exports = {
reporter: function(results, data, opts) {
const errors = results.filter(r => r.error);
if (errors.length === 0) {
return; // No errors to report
}
const message = {
text: `JSHint found ${errors.length} issues`,
attachments: errors.slice(0, 10).map(result => ({
color: result.error.code.startsWith('E') ? 'danger' : 'warning',
fields: [
{
title: 'File',
value: result.file,
short: true
},
{
title: 'Line',
value: result.error.line,
short: true
},
{
title: 'Message',
value: result.error.reason,
short: false
}
]
}))
};
// Send to Slack webhook (URL from environment)
const webhookUrl = process.env.SLACK_WEBHOOK_URL;
if (webhookUrl) {
// Implementation for posting to Slack webhook
console.log('Posting to Slack:', JSON.stringify(message, null, 2));
} else {
console.log('SLACK_WEBHOOK_URL not set');
}
}
};Options passed to reporters for customization.
interface ReporterOptions {
/**
* Show error codes in output
*/
verbose: boolean;
/**
* Filename to use for stdin input
*/
filename?: string;
/**
* Show additional JSHint data beyond errors
*/
'show-non-errors': boolean;
/**
* Custom options specific to reporter implementation
*/
[key: string]: any;
}GitHub Actions:
- name: Run JSHint
run: |
jshint --reporter checkstyle src/ > jshint-report.xml
- name: Publish JSHint Results
uses: dorny/test-reporter@v1
if: always()
with:
name: JSHint Results
path: jshint-report.xml
reporter: java-junitWebpack Integration:
// webpack.config.js
const jshint = require('jshint').JSHINT;
class JSHintPlugin {
apply(compiler) {
compiler.hooks.emit.tap('JSHintPlugin', (compilation) => {
// Custom reporter for webpack builds
const reporter = {
reporter: function(results) {
results.forEach(result => {
if (result.error) {
const message = `${result.file}:${result.error.line}:${result.error.character} ${result.error.reason}`;
compilation.warnings.push(new Error(message));
}
});
}
};
// Use reporter with JSHint
});
}
}Gulp Integration:
const gulp = require('gulp');
const jshint = require('gulp-jshint');
gulp.task('lint', function() {
return gulp.src('src/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('unix'))
.pipe(jshint.reporter('fail')); // Fail build on errors
});