0
# jest-runner-eslint
1
2
jest-runner-eslint is a Jest runner that integrates ESLint into the Jest testing framework, allowing developers to run ESLint as part of their Jest test suite. It enables linting to be treated as tests, providing a unified interface for both code testing and code quality checks with seamless integration for JavaScript and TypeScript projects.
3
4
## Package Information
5
6
- **Package Name**: jest-runner-eslint
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install jest-runner-eslint`
10
11
## Core Imports
12
13
```javascript
14
// Main Jest runner (CommonJS only)
15
const jestRunner = require("jest-runner-eslint");
16
17
// Watch plugin
18
const ESLintWatchFixPlugin = require("jest-runner-eslint/watch-fix");
19
```
20
21
## Basic Usage
22
23
### Standalone Configuration
24
25
```javascript
26
// jest.config.js
27
module.exports = {
28
runner: 'jest-runner-eslint',
29
displayName: 'lint',
30
testMatch: ['<rootDir>/src/**/*.js'],
31
};
32
```
33
34
### Multi-Project Configuration
35
36
```javascript
37
// jest.config.js
38
module.exports = {
39
projects: [
40
{
41
displayName: 'test',
42
// your regular Jest test configuration
43
},
44
{
45
runner: 'jest-runner-eslint',
46
displayName: 'lint',
47
testMatch: ['<rootDir>/src/**/*.js'],
48
},
49
],
50
};
51
```
52
53
### With Configuration Options
54
55
```javascript
56
// jest-runner-eslint.config.js
57
module.exports = {
58
cliOptions: {
59
fix: true,
60
cache: true,
61
format: 'codeframe',
62
maxWarnings: 0,
63
},
64
};
65
```
66
67
## Architecture
68
69
jest-runner-eslint is built around several key components:
70
71
- **Main Runner**: Jest runner that orchestrates ESLint execution within Jest framework
72
- **ESLint Integration**: Core execution engine that runs ESLint and formats results for Jest
73
- **Configuration System**: Flexible configuration loading using cosmiconfig with support for both legacy and flat ESLint configs
74
- **ESLint Compatibility Layer**: Automatic detection and handling of ESLint versions (8.57.0+) and configuration types (flat vs legacy)
75
- **Watch Plugin**: Interactive Jest watch mode plugin for toggling --fix option during development
76
- **Results Formatting**: Transforms ESLint output into Jest-compatible test results with proper error reporting
77
78
### ESLint Version Compatibility
79
80
The runner automatically detects and handles different ESLint versions and configuration formats:
81
82
- **ESLint 8.57.0+**: Uses `loadESLint()` function to detect flat config vs legacy config automatically
83
- **ESLint <8.57.0**: Falls back to compatibility mode using `ESLint` and `FlatESLint` constructors
84
- **Configuration Detection**: Automatically determines whether to use flat config or legacy config format
85
- **API Normalization**: Provides unified interface regardless of underlying ESLint version
86
87
## Capabilities
88
89
### Main Jest Runner
90
91
The primary Jest runner that integrates ESLint into Jest testing workflow, supporting all ESLint configurations and providing Jest-formatted output.
92
93
```javascript { .api }
94
const runner = require("jest-runner-eslint");
95
```
96
97
[Jest Runner Integration](./jest-runner.md)
98
99
### Watch Mode Plugin
100
101
Interactive Jest watch plugin that allows toggling ESLint's --fix option during development without restarting the watch process.
102
103
```javascript { .api }
104
class ESLintWatchFixPlugin {
105
constructor(options: WatchPluginOptions);
106
run(): Promise<boolean>;
107
getUsageInfo(): WatchPluginUsageInfo;
108
}
109
110
interface WatchPluginOptions {
111
stdout: NodeJS.WriteStream;
112
config: { key?: string };
113
}
114
115
interface WatchPluginUsageInfo {
116
key: string;
117
prompt: string;
118
}
119
```
120
121
[Watch Plugin](./watch-plugin.md)
122
123
### Configuration Management
124
125
Comprehensive configuration system supporting all ESLint CLI options with automatic detection of ESLint configuration type (legacy vs flat config).
126
127
```javascript { .api }
128
interface JestRunnerESLintConfig {
129
cliOptions?: ESLintCliOptions;
130
}
131
132
interface ESLintCliOptions {
133
// Basic options
134
cache?: boolean;
135
cacheLocation?: string;
136
config?: string;
137
fix?: boolean;
138
fixDryRun?: boolean;
139
format?: string;
140
maxWarnings?: number;
141
quiet?: boolean;
142
143
// Legacy config options (ESLint <8.57.0)
144
ext?: string | string[];
145
env?: string | string[];
146
global?: string | string[];
147
ignorePath?: string;
148
ignorePattern?: string[];
149
noEslintrc?: boolean;
150
noIgnore?: boolean;
151
noInlineConfig?: boolean;
152
parser?: string;
153
parserOptions?: object;
154
plugin?: string | string[];
155
reportUnusedDisableDirectives?: boolean;
156
resolvePluginsRelativeTo?: string;
157
rules?: object;
158
rulesdir?: string | string[];
159
}
160
```
161
162
[Configuration](./configuration.md)
163
164
### Configuration Utilities
165
166
Internal utilities for configuration management and normalization across different ESLint versions and configuration formats.
167
168
```javascript { .api }
169
/**
170
* Configuration override management for watch mode
171
*/
172
class ConfigOverrides {
173
setFix(fix: boolean): void;
174
getFix(): boolean | undefined;
175
}
176
177
/**
178
* Configuration normalization for ESLint options
179
* @param configType - ESLint configuration type ('flat' | 'legacy')
180
* @param config - Raw configuration object
181
* @returns Normalized configuration with cliOptions
182
*/
183
function normalizeConfig(
184
configType: 'flat' | 'legacy',
185
config: object
186
): { cliOptions: ESLintCliOptions };
187
```
188
189
## Types
190
191
```javascript { .api }
192
interface ESLintResult {
193
filePath: string;
194
messages: ESLintMessage[];
195
errorCount: number;
196
fatalErrorCount?: number;
197
warningCount: number;
198
fixableErrorCount: number;
199
fixableWarningCount: number;
200
source?: string;
201
usedDeprecatedRules?: Array<{ ruleId: string; replacedBy: string[] }>;
202
}
203
204
interface ESLintMessage {
205
ruleId: string | null;
206
severity: 1 | 2;
207
message: string;
208
line: number;
209
column: number;
210
nodeType?: string;
211
messageId?: string;
212
endLine?: number;
213
endColumn?: number;
214
fix?: ESLintFix;
215
suggestions?: ESLintSuggestion[];
216
}
217
218
interface ESLintFix {
219
range: [number, number];
220
text: string;
221
}
222
223
interface ESLintSuggestion {
224
desc: string;
225
messageId?: string;
226
fix: ESLintFix;
227
}
228
229
interface TestResult {
230
failureMessage: string;
231
leaks: boolean;
232
numFailingTests: number;
233
numPassingTests: number;
234
numPendingTests: number;
235
numTodoTests: number;
236
openHandles: any[];
237
perfStats: {
238
start: number;
239
end: number;
240
duration: number;
241
runtime: number;
242
slow: boolean;
243
};
244
skipped: boolean;
245
snapshot: {
246
added: number;
247
fileDeleted: boolean;
248
matched: number;
249
unchecked: number;
250
uncheckedKeys: any[];
251
unmatched: number;
252
updated: number;
253
};
254
testFilePath: string;
255
testResults: TestAssertionResult[];
256
cliOptions?: ESLintCliOptions;
257
}
258
259
interface TestAssertionResult {
260
duration: number;
261
ancestorTitles: string[];
262
failureDetails: any[];
263
failureMessages: string[];
264
fullName: string;
265
location?: {
266
column: number;
267
line: number;
268
};
269
testFilePath: string;
270
numPassingAsserts: number;
271
status: 'passed' | 'failed' | 'skipped';
272
title: string;
273
}
274
```