@@ -10,7 +10,9 @@ const { arrify, parseFiles, parseFoldersToGlobs } = require('./utils');
10
10
/** @typedef {import('./options').Options } Options */
11
11
12
12
const ESLINT_PLUGIN = 'ESLintWebpackPlugin' ;
13
- let counter = 0 ;
13
+ const DEFAULT_FOLDER_TO_EXCLUDE = '**/node_modules/**' ;
14
+
15
+ let compilerId = 0 ;
14
16
15
17
class ESLintWebpackPlugin {
16
18
/**
@@ -29,26 +31,30 @@ class ESLintWebpackPlugin {
29
31
apply ( compiler ) {
30
32
// Generate key for each compilation,
31
33
// this differentiates one from the other when being cached.
32
- this . key = compiler . name || `${ this . key } _${ ( counter += 1 ) } ` ;
34
+ this . key = compiler . name || `${ this . key } _${ ( compilerId += 1 ) } ` ;
35
+
36
+ const excludedFiles = parseFiles (
37
+ this . options . exclude || [ ] ,
38
+ this . getContext ( compiler )
39
+ ) ;
40
+ const resourceQueries = arrify ( this . options . resourceQueryExclude || [ ] ) ;
41
+ const excludedResourceQueries = resourceQueries . map ( ( item ) =>
42
+ item instanceof RegExp ? item : new RegExp ( item )
43
+ ) ;
33
44
34
45
const options = {
35
46
...this . options ,
36
- exclude : parseFiles (
37
- this . options . exclude || [ ] ,
38
- this . getContext ( compiler )
39
- ) ,
47
+ exclude : excludedFiles ,
48
+ resourceQueryExclude : excludedResourceQueries ,
40
49
extensions : arrify ( this . options . extensions ) ,
41
- resourceQueryExclude : arrify ( this . options . resourceQueryExclude || [ ] ) . map (
42
- ( item ) => ( item instanceof RegExp ? item : new RegExp ( item ) )
43
- ) ,
44
50
files : parseFiles ( this . options . files || '' , this . getContext ( compiler ) ) ,
45
51
} ;
46
52
53
+ const foldersToExclude = this . options . exclude
54
+ ? options . exclude
55
+ : DEFAULT_FOLDER_TO_EXCLUDE ;
56
+ const exclude = parseFoldersToGlobs ( foldersToExclude ) ;
47
57
const wanted = parseFoldersToGlobs ( options . files , options . extensions ) ;
48
- const exclude = parseFoldersToGlobs (
49
- this . options . exclude ? options . exclude : '**/node_modules/**' ,
50
- [ ]
51
- ) ;
52
58
53
59
// If `lintDirtyModulesOnly` is disabled,
54
60
// execute the linter on the build
@@ -58,15 +64,15 @@ class ESLintWebpackPlugin {
58
64
) ;
59
65
}
60
66
61
- let isFirstRun = this . options . lintDirtyModulesOnly ;
67
+ let hasCompilerRunByDirtyModule = this . options . lintDirtyModulesOnly ;
68
+
62
69
compiler . hooks . watchRun . tapPromise ( this . key , ( c ) => {
63
- if ( isFirstRun ) {
64
- isFirstRun = false ;
70
+ if ( ! hasCompilerRunByDirtyModule )
71
+ return this . run ( c , options , wanted , exclude ) ;
65
72
66
- return Promise . resolve ( ) ;
67
- }
73
+ hasCompilerRunByDirtyModule = false ;
68
74
69
- return this . run ( c , options , wanted , exclude ) ;
75
+ return Promise . resolve ( ) ;
70
76
} ) ;
71
77
}
72
78
@@ -77,13 +83,12 @@ class ESLintWebpackPlugin {
77
83
* @param {string[] } exclude
78
84
*/
79
85
async run ( compiler , options , wanted , exclude ) {
80
- // Do not re-hook
81
- if (
82
- // @ts -ignore
83
- compiler . hooks . compilation . taps . find ( ( { name } ) => name === this . key )
84
- ) {
85
- return ;
86
- }
86
+ // @ts -ignore
87
+ const isCompilerHooked = compiler . hooks . compilation . taps . find (
88
+ ( { name } ) => name === this . key
89
+ ) ;
90
+
91
+ if ( isCompilerHooked ) return ;
87
92
88
93
compiler . hooks . compilation . tap ( this . key , ( compilation ) => {
89
94
/** @type {import('./linter').Linter } */
@@ -106,30 +111,27 @@ class ESLintWebpackPlugin {
106
111
// @ts -ignore
107
112
// Add the file to be linted
108
113
compilation . hooks . succeedModule . tap ( this . key , ( { resource } ) => {
109
- if ( resource ) {
110
- const [ file , query ] = resource . split ( '?' ) ;
111
-
112
- if (
113
- file &&
114
- ! files . includes ( file ) &&
115
- isMatch ( file , wanted , { dot : true } ) &&
116
- ! isMatch ( file , exclude , { dot : true } ) &&
117
- options . resourceQueryExclude . every ( ( reg ) => ! reg . test ( query ) )
118
- ) {
119
- files . push ( file ) ;
120
-
121
- if ( threads > 1 ) {
122
- lint ( file ) ;
123
- }
124
- }
114
+ if ( ! resource ) return ;
115
+
116
+ const [ file , query ] = resource . split ( '?' ) ;
117
+ const isFileNotListed = file && ! files . includes ( file ) ;
118
+ const isFileWanted =
119
+ isMatch ( file , wanted , { dot : true } ) &&
120
+ ! isMatch ( file , exclude , { dot : true } ) ;
121
+ const isQueryNotExclude = options . resourceQueryExclude . every (
122
+ ( reg ) => ! reg . test ( query )
123
+ ) ;
124
+
125
+ if ( isFileNotListed && isFileWanted && isQueryNotExclude ) {
126
+ files . push ( file ) ;
127
+
128
+ if ( threads > 1 ) lint ( file ) ;
125
129
}
126
130
} ) ;
127
131
128
132
// Lint all files added
129
133
compilation . hooks . finishModules . tap ( this . key , ( ) => {
130
- if ( files . length > 0 && threads <= 1 ) {
131
- lint ( files ) ;
132
- }
134
+ if ( files . length > 0 && threads <= 1 ) lint ( files ) ;
133
135
} ) ;
134
136
135
137
// await and interpret results
@@ -141,22 +143,20 @@ class ESLintWebpackPlugin {
141
143
if ( warnings && ! options . failOnWarning ) {
142
144
// @ts -ignore
143
145
compilation . warnings . push ( warnings ) ;
144
- } else if ( warnings && options . failOnWarning ) {
146
+ } else if ( warnings ) {
145
147
// @ts -ignore
146
148
compilation . errors . push ( warnings ) ;
147
149
}
148
150
149
- if ( errors && options . failOnError ) {
150
- // @ts -ignore
151
- compilation . errors . push ( errors ) ;
152
- } else if ( errors && ! options . failOnError ) {
151
+ if ( errors && ! options . failOnError ) {
153
152
// @ts -ignore
154
153
compilation . warnings . push ( errors ) ;
154
+ } else if ( errors ) {
155
+ // @ts -ignore
156
+ compilation . errors . push ( errors ) ;
155
157
}
156
158
157
- if ( generateReportAsset ) {
158
- await generateReportAsset ( compilation ) ;
159
- }
159
+ if ( generateReportAsset ) await generateReportAsset ( compilation ) ;
160
160
}
161
161
} ) ;
162
162
}
@@ -167,15 +167,14 @@ class ESLintWebpackPlugin {
167
167
* @returns {string }
168
168
*/
169
169
getContext ( compiler ) {
170
- if ( ! this . options . context ) {
171
- return String ( compiler . options . context ) ;
172
- }
170
+ const compilerContext = String ( compiler . options . context ) ;
171
+ const optionContext = this . options . context ;
173
172
174
- if ( ! isAbsolute ( this . options . context ) ) {
175
- return join ( String ( compiler . options . context ) , this . options . context ) ;
176
- }
173
+ if ( ! optionContext ) return compilerContext ;
174
+
175
+ if ( isAbsolute ( optionContext ) ) return optionContext ;
177
176
178
- return this . options . context ;
177
+ return join ( compilerContext , optionContext ) ;
179
178
}
180
179
}
181
180
0 commit comments