stylelint-webpack-plugin 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/StylelintError.js +0 -2
- package/dist/getStylelint.js +32 -37
- package/dist/index.js +32 -63
- package/dist/linter.js +76 -86
- package/dist/options.js +14 -17
- package/dist/utils.js +7 -20
- package/dist/worker.js +11 -11
- package/package.json +19 -19
- package/types/getStylelint.d.ts +16 -52
- package/types/linter.d.ts +16 -66
- package/types/options.d.ts +4 -61
- package/types/worker.d.ts +2 -57
package/dist/StylelintError.js
CHANGED
package/dist/getStylelint.js
CHANGED
|
@@ -3,94 +3,94 @@
|
|
|
3
3
|
const {
|
|
4
4
|
cpus
|
|
5
5
|
} = require('os');
|
|
6
|
-
|
|
7
6
|
const {
|
|
8
7
|
Worker: JestWorker
|
|
9
|
-
} = require('jest-worker');
|
|
10
|
-
|
|
8
|
+
} = require('jest-worker');
|
|
11
9
|
|
|
10
|
+
// @ts-ignore
|
|
12
11
|
const {
|
|
13
12
|
setup,
|
|
14
13
|
lintFiles
|
|
15
14
|
} = require('./worker');
|
|
16
|
-
|
|
17
15
|
const {
|
|
18
16
|
jsonStringifyReplacerSortKeys
|
|
19
17
|
} = require('./utils');
|
|
20
|
-
|
|
21
18
|
const {
|
|
22
19
|
getStylelintOptions
|
|
23
20
|
} = require('./options');
|
|
24
|
-
/** @type {{[key: string]: any}} */
|
|
25
|
-
|
|
26
21
|
|
|
22
|
+
/** @type {{[key: string]: any}} */
|
|
27
23
|
const cache = {};
|
|
28
|
-
/** @typedef {import('stylelint')} Stylelint */
|
|
29
24
|
|
|
25
|
+
/** @typedef {{lint: (options: LinterOptions) => Promise<LinterResult>, formatters: { [k: string]: Formatter }}} Stylelint */
|
|
30
26
|
/** @typedef {import('stylelint').LintResult} LintResult */
|
|
31
|
-
|
|
27
|
+
/** @typedef {import('stylelint').LinterOptions} LinterOptions */
|
|
28
|
+
/** @typedef {import('stylelint').LinterResult} LinterResult */
|
|
29
|
+
/** @typedef {import('stylelint').Formatter} Formatter */
|
|
30
|
+
/** @typedef {import('stylelint').FormatterType} FormatterType */
|
|
32
31
|
/** @typedef {import('./options').Options} Options */
|
|
33
|
-
|
|
32
|
+
/** @typedef {(stylelint: Stylelint, filePath: string) => Promise<boolean>} isPathIgnored */
|
|
34
33
|
/** @typedef {() => Promise<void>} AsyncTask */
|
|
35
|
-
|
|
36
34
|
/** @typedef {(files: string|string[]) => Promise<LintResult[]>} LintTask */
|
|
37
|
-
|
|
38
|
-
/** @typedef {{api: import('stylelint').InternalApi, stylelint: Stylelint, lintFiles: LintTask, cleanup: AsyncTask, threads: number, }} Linter */
|
|
39
|
-
|
|
35
|
+
/** @typedef {{stylelint: Stylelint, isPathIgnored: isPathIgnored, lintFiles: LintTask, cleanup: AsyncTask, threads: number }} Linter */
|
|
40
36
|
/** @typedef {JestWorker & {lintFiles: LintTask}} Worker */
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
39
|
* @param {Options} options
|
|
44
40
|
* @returns {Linter}
|
|
45
41
|
*/
|
|
46
|
-
|
|
47
42
|
function loadStylelint(options) {
|
|
48
43
|
const stylelintOptions = getStylelintOptions(options);
|
|
49
44
|
const stylelint = setup(options, stylelintOptions);
|
|
45
|
+
|
|
46
|
+
/** @type {isPathIgnored} */
|
|
47
|
+
let isPathIgnored;
|
|
48
|
+
try {
|
|
49
|
+
isPathIgnored = require(`${options.stylelintPath}/lib/isPathIgnored`);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
try {
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
isPathIgnored = require('stylelint/lib/isPathIgnored');
|
|
54
|
+
} catch (_) {
|
|
55
|
+
isPathIgnored = () => Promise.resolve(false);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
50
58
|
return {
|
|
51
59
|
stylelint,
|
|
52
|
-
|
|
60
|
+
isPathIgnored,
|
|
53
61
|
lintFiles,
|
|
54
62
|
cleanup: async () => {},
|
|
55
63
|
threads: 1
|
|
56
64
|
};
|
|
57
65
|
}
|
|
66
|
+
|
|
58
67
|
/**
|
|
59
68
|
* @param {string|undefined} key
|
|
60
69
|
* @param {number} poolSize
|
|
61
70
|
* @param {Options} options
|
|
62
71
|
* @returns {Linter}
|
|
63
72
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
73
|
function loadStylelintThreaded(key, poolSize, options) {
|
|
67
74
|
const cacheKey = getCacheKey(key, options);
|
|
68
|
-
|
|
69
75
|
const source = require.resolve('./worker');
|
|
70
|
-
|
|
71
76
|
const workerOptions = {
|
|
72
77
|
enableWorkerThreads: true,
|
|
73
78
|
numWorkers: poolSize,
|
|
74
79
|
setupArgs: [options, getStylelintOptions(options)]
|
|
75
80
|
};
|
|
76
81
|
const local = loadStylelint(options);
|
|
77
|
-
let worker =
|
|
78
|
-
/** @type {Worker?} */
|
|
79
|
-
new JestWorker(source, workerOptions);
|
|
80
|
-
/** @type {Linter} */
|
|
82
|
+
let worker = /** @type {Worker?} */new JestWorker(source, workerOptions);
|
|
81
83
|
|
|
82
|
-
|
|
84
|
+
/** @type {Linter} */
|
|
85
|
+
const context = {
|
|
86
|
+
...local,
|
|
83
87
|
threads: poolSize,
|
|
84
|
-
lintFiles: async files =>
|
|
85
|
-
/* istanbul ignore next */
|
|
88
|
+
lintFiles: async files => /* istanbul ignore next */
|
|
86
89
|
worker ? worker.lintFiles(files) : local.lintFiles(files),
|
|
87
90
|
cleanup: async () => {
|
|
88
91
|
cache[cacheKey] = local;
|
|
89
|
-
|
|
90
92
|
context.lintFiles = files => local.lintFiles(files);
|
|
91
93
|
/* istanbul ignore next */
|
|
92
|
-
|
|
93
|
-
|
|
94
94
|
if (worker) {
|
|
95
95
|
worker.end();
|
|
96
96
|
worker = null;
|
|
@@ -99,13 +99,12 @@ function loadStylelintThreaded(key, poolSize, options) {
|
|
|
99
99
|
};
|
|
100
100
|
return context;
|
|
101
101
|
}
|
|
102
|
+
|
|
102
103
|
/**
|
|
103
104
|
* @param {string|undefined} key
|
|
104
105
|
* @param {Options} options
|
|
105
106
|
* @returns {Linter}
|
|
106
107
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
108
|
function getStylelint(key, {
|
|
110
109
|
threads,
|
|
111
110
|
...options
|
|
@@ -115,25 +114,21 @@ function getStylelint(key, {
|
|
|
115
114
|
threads,
|
|
116
115
|
...options
|
|
117
116
|
});
|
|
118
|
-
|
|
119
117
|
if (!cache[cacheKey]) {
|
|
120
118
|
cache[cacheKey] = max > 1 ? loadStylelintThreaded(key, max, options) : loadStylelint(options);
|
|
121
119
|
}
|
|
122
|
-
|
|
123
120
|
return cache[cacheKey];
|
|
124
121
|
}
|
|
122
|
+
|
|
125
123
|
/**
|
|
126
124
|
* @param {string|undefined} key
|
|
127
125
|
* @param {Options} options
|
|
128
126
|
* @returns {string}
|
|
129
127
|
*/
|
|
130
|
-
|
|
131
|
-
|
|
132
128
|
function getCacheKey(key, options) {
|
|
133
129
|
return JSON.stringify({
|
|
134
130
|
key,
|
|
135
131
|
options
|
|
136
132
|
}, jsonStringifyReplacerSortKeys);
|
|
137
133
|
}
|
|
138
|
-
|
|
139
134
|
module.exports = getStylelint;
|
package/dist/index.js
CHANGED
|
@@ -4,37 +4,27 @@ const {
|
|
|
4
4
|
isAbsolute,
|
|
5
5
|
join
|
|
6
6
|
} = require('path');
|
|
7
|
-
|
|
8
7
|
const arrify = require('arrify');
|
|
9
|
-
|
|
10
8
|
const globby = require('globby');
|
|
11
|
-
|
|
12
9
|
const {
|
|
13
10
|
isMatch
|
|
14
11
|
} = require('micromatch');
|
|
15
|
-
|
|
16
12
|
const {
|
|
17
13
|
getOptions
|
|
18
14
|
} = require('./options');
|
|
19
|
-
|
|
20
15
|
const linter = require('./linter');
|
|
21
|
-
|
|
22
16
|
const {
|
|
23
17
|
parseFiles,
|
|
24
18
|
parseFoldersToGlobs
|
|
25
19
|
} = require('./utils');
|
|
26
|
-
/** @typedef {import('webpack').Compiler} Compiler */
|
|
27
20
|
|
|
21
|
+
/** @typedef {import('webpack').Compiler} Compiler */
|
|
28
22
|
/** @typedef {import('webpack').Module} Module */
|
|
29
|
-
|
|
30
23
|
/** @typedef {import('./options').Options} Options */
|
|
31
|
-
|
|
32
24
|
/** @typedef {Partial<{timestamp:number} | number>} FileSystemInfoEntry */
|
|
33
25
|
|
|
34
|
-
|
|
35
26
|
const STYLELINT_PLUGIN = 'StylelintWebpackPlugin';
|
|
36
27
|
let counter = 0;
|
|
37
|
-
|
|
38
28
|
class StylelintWebpackPlugin {
|
|
39
29
|
/**
|
|
40
30
|
* @param {Options} options
|
|
@@ -44,82 +34,82 @@ class StylelintWebpackPlugin {
|
|
|
44
34
|
this.options = getOptions(options);
|
|
45
35
|
this.run = this.run.bind(this);
|
|
46
36
|
this.startTime = Date.now();
|
|
47
|
-
/** @type {ReadonlyMap<string, null | FileSystemInfoEntry | "ignore" | undefined>} */
|
|
48
37
|
|
|
38
|
+
/** @type {ReadonlyMap<string, null | FileSystemInfoEntry | "ignore" | undefined>} */
|
|
49
39
|
this.prevTimestamps = new Map();
|
|
50
40
|
}
|
|
41
|
+
|
|
51
42
|
/**
|
|
52
43
|
* @param {Compiler} compiler
|
|
53
44
|
* @returns {void}
|
|
54
45
|
*/
|
|
55
|
-
|
|
56
|
-
|
|
57
46
|
apply(compiler) {
|
|
58
47
|
// Generate key for each compilation,
|
|
59
48
|
// this differentiates one from the other when being cached.
|
|
60
49
|
this.key = compiler.name || `${this.key}_${counter += 1}`;
|
|
61
50
|
const context = this.getContext(compiler);
|
|
62
51
|
const excludeDefault = ['**/node_modules/**', String(compiler.options.output.path)];
|
|
63
|
-
const options = {
|
|
52
|
+
const options = {
|
|
53
|
+
...this.options,
|
|
64
54
|
context,
|
|
65
55
|
exclude: parseFiles(this.options.exclude || excludeDefault, context),
|
|
66
56
|
extensions: arrify(this.options.extensions),
|
|
67
57
|
files: parseFiles(this.options.files || '', context)
|
|
68
58
|
};
|
|
69
59
|
const wanted = parseFoldersToGlobs(options.files, options.extensions);
|
|
70
|
-
const exclude = parseFoldersToGlobs(options.exclude);
|
|
71
|
-
// execute the linter on the build
|
|
60
|
+
const exclude = parseFoldersToGlobs(options.exclude);
|
|
72
61
|
|
|
62
|
+
// If `lintDirtyModulesOnly` is disabled,
|
|
63
|
+
// execute the linter on the build
|
|
73
64
|
if (!this.options.lintDirtyModulesOnly) {
|
|
74
65
|
compiler.hooks.run.tapPromise(this.key, c => this.run(c, options, wanted, exclude));
|
|
75
66
|
}
|
|
76
|
-
|
|
77
67
|
let isFirstRun = this.options.lintDirtyModulesOnly;
|
|
78
68
|
compiler.hooks.watchRun.tapPromise(this.key, c => {
|
|
79
69
|
if (isFirstRun) {
|
|
80
70
|
isFirstRun = false;
|
|
81
71
|
return Promise.resolve();
|
|
82
72
|
}
|
|
83
|
-
|
|
84
73
|
return this.run(c, options, wanted, exclude);
|
|
85
74
|
});
|
|
86
75
|
}
|
|
76
|
+
|
|
87
77
|
/**
|
|
88
78
|
* @param {Compiler} compiler
|
|
89
79
|
* @param {Options} options
|
|
90
80
|
* @param {string[]} wanted
|
|
91
81
|
* @param {string[]} exclude
|
|
92
82
|
*/
|
|
93
|
-
|
|
94
|
-
|
|
95
83
|
async run(compiler, options, wanted, exclude) {
|
|
96
84
|
// Do not re-hook
|
|
97
|
-
|
|
98
85
|
/* istanbul ignore if */
|
|
99
|
-
if (
|
|
86
|
+
if (
|
|
87
|
+
// @ts-ignore
|
|
100
88
|
compiler.hooks.thisCompilation.taps.find(({
|
|
101
89
|
name
|
|
102
90
|
}) => name === this.key)) {
|
|
103
91
|
return;
|
|
104
92
|
}
|
|
105
|
-
|
|
106
93
|
compiler.hooks.thisCompilation.tap(this.key, compilation => {
|
|
94
|
+
/** @type {import('./getStylelint').Stylelint} */
|
|
95
|
+
let stylelint;
|
|
96
|
+
|
|
107
97
|
/** @type {import('./linter').Linter} */
|
|
108
98
|
let lint;
|
|
109
|
-
/** @type {import('stylelint').InternalApi} */
|
|
110
99
|
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
/** @type {import('./linter').isPathIgnored} */
|
|
101
|
+
let isPathIgnored;
|
|
113
102
|
|
|
103
|
+
/** @type {import('./linter').Reporter} */
|
|
114
104
|
let report;
|
|
115
|
-
/** @type number */
|
|
116
105
|
|
|
106
|
+
/** @type number */
|
|
117
107
|
let threads;
|
|
118
|
-
|
|
119
108
|
try {
|
|
120
109
|
({
|
|
110
|
+
stylelint,
|
|
121
111
|
lint,
|
|
122
|
-
|
|
112
|
+
isPathIgnored,
|
|
123
113
|
report,
|
|
124
114
|
threads
|
|
125
115
|
} = linter(this.key, options, compilation));
|
|
@@ -127,20 +117,16 @@ class StylelintWebpackPlugin {
|
|
|
127
117
|
compilation.errors.push(e);
|
|
128
118
|
return;
|
|
129
119
|
}
|
|
130
|
-
|
|
131
120
|
compilation.hooks.finishModules.tapPromise(this.key, async () => {
|
|
132
121
|
/** @type {string[]} */
|
|
133
122
|
// @ts-ignore
|
|
134
|
-
const files = (await Promise.all(this.getFiles(compiler, wanted, exclude).map(async (
|
|
135
|
-
/** @type {string | undefined} */
|
|
136
|
-
file) => {
|
|
123
|
+
const files = (await Promise.all(this.getFiles(compiler, wanted, exclude).map(async ( /** @type {string} */file) => {
|
|
137
124
|
try {
|
|
138
|
-
return (await
|
|
125
|
+
return (await isPathIgnored(stylelint, file)) ? false : file;
|
|
139
126
|
} catch (e) {
|
|
140
127
|
return file;
|
|
141
128
|
}
|
|
142
129
|
}))).filter(file => file !== false);
|
|
143
|
-
|
|
144
130
|
if (threads > 1) {
|
|
145
131
|
for (const file of files) {
|
|
146
132
|
lint(parseFiles(file, options.context || ''));
|
|
@@ -148,17 +134,16 @@ class StylelintWebpackPlugin {
|
|
|
148
134
|
} else if (files.length > 0) {
|
|
149
135
|
lint(parseFiles(files, options.context || ''));
|
|
150
136
|
}
|
|
151
|
-
});
|
|
137
|
+
});
|
|
152
138
|
|
|
139
|
+
// await and interpret results
|
|
153
140
|
compilation.hooks.additionalAssets.tapPromise(this.key, processResults);
|
|
154
|
-
|
|
155
141
|
async function processResults() {
|
|
156
142
|
const {
|
|
157
143
|
errors,
|
|
158
144
|
warnings,
|
|
159
145
|
generateReportAsset
|
|
160
146
|
} = await report();
|
|
161
|
-
|
|
162
147
|
if (warnings && !options.failOnWarning) {
|
|
163
148
|
// @ts-ignore
|
|
164
149
|
compilation.warnings.push(warnings);
|
|
@@ -166,7 +151,6 @@ class StylelintWebpackPlugin {
|
|
|
166
151
|
// @ts-ignore
|
|
167
152
|
compilation.errors.push(warnings);
|
|
168
153
|
}
|
|
169
|
-
|
|
170
154
|
if (errors && options.failOnError) {
|
|
171
155
|
// @ts-ignore
|
|
172
156
|
compilation.errors.push(errors);
|
|
@@ -174,31 +158,28 @@ class StylelintWebpackPlugin {
|
|
|
174
158
|
// @ts-ignore
|
|
175
159
|
compilation.warnings.push(errors);
|
|
176
160
|
}
|
|
177
|
-
|
|
178
161
|
if (generateReportAsset) {
|
|
179
162
|
await generateReportAsset(compilation);
|
|
180
163
|
}
|
|
181
164
|
}
|
|
182
165
|
});
|
|
183
166
|
}
|
|
167
|
+
|
|
184
168
|
/**
|
|
185
169
|
*
|
|
186
170
|
* @param {Compiler} compiler
|
|
187
171
|
* @returns {string}
|
|
188
172
|
*/
|
|
189
|
-
|
|
190
|
-
|
|
191
173
|
getContext(compiler) {
|
|
192
174
|
if (!this.options.context) {
|
|
193
175
|
return String(compiler.options.context);
|
|
194
176
|
}
|
|
195
|
-
|
|
196
177
|
if (!isAbsolute(this.options.context)) {
|
|
197
178
|
return join(String(compiler.options.context), this.options.context);
|
|
198
179
|
}
|
|
199
|
-
|
|
200
180
|
return this.options.context;
|
|
201
181
|
}
|
|
182
|
+
|
|
202
183
|
/**
|
|
203
184
|
* @param {Compiler} compiler
|
|
204
185
|
* @param {string[]} wanted
|
|
@@ -206,8 +187,6 @@ class StylelintWebpackPlugin {
|
|
|
206
187
|
* @returns {string[]}
|
|
207
188
|
*/
|
|
208
189
|
// eslint-disable-next-line no-unused-vars
|
|
209
|
-
|
|
210
|
-
|
|
211
190
|
getFiles(compiler, wanted, exclude) {
|
|
212
191
|
// webpack 5
|
|
213
192
|
if (compiler.modifiedFiles) {
|
|
@@ -216,11 +195,10 @@ class StylelintWebpackPlugin {
|
|
|
216
195
|
}) && !isMatch(file, exclude, {
|
|
217
196
|
dot: true
|
|
218
197
|
}));
|
|
219
|
-
}
|
|
198
|
+
}
|
|
220
199
|
|
|
200
|
+
// webpack 4
|
|
221
201
|
/* istanbul ignore next */
|
|
222
|
-
|
|
223
|
-
|
|
224
202
|
if (compiler.fileTimestamps && compiler.fileTimestamps.size > 0) {
|
|
225
203
|
return this.getChangedFiles(compiler.fileTimestamps).filter(file => isMatch(file, wanted, {
|
|
226
204
|
dot: true
|
|
@@ -228,20 +206,17 @@ class StylelintWebpackPlugin {
|
|
|
228
206
|
dot: true
|
|
229
207
|
}));
|
|
230
208
|
}
|
|
231
|
-
|
|
232
209
|
return globby.sync(wanted, {
|
|
233
210
|
dot: true,
|
|
234
211
|
ignore: exclude
|
|
235
212
|
});
|
|
236
213
|
}
|
|
214
|
+
|
|
237
215
|
/**
|
|
238
216
|
* @param {ReadonlyMap<string, null | FileSystemInfoEntry | "ignore" | undefined>} fileTimestamps
|
|
239
217
|
* @returns {string[]}
|
|
240
218
|
*/
|
|
241
|
-
|
|
242
219
|
/* istanbul ignore next */
|
|
243
|
-
|
|
244
|
-
|
|
245
220
|
getChangedFiles(fileTimestamps) {
|
|
246
221
|
/**
|
|
247
222
|
* @param {null | FileSystemInfoEntry | "ignore" | undefined} fileSystemInfoEntry
|
|
@@ -252,36 +227,30 @@ class StylelintWebpackPlugin {
|
|
|
252
227
|
if (fileSystemInfoEntry && fileSystemInfoEntry.timestamp) {
|
|
253
228
|
// @ts-ignore
|
|
254
229
|
return fileSystemInfoEntry.timestamp;
|
|
255
|
-
}
|
|
256
|
-
|
|
230
|
+
}
|
|
257
231
|
|
|
232
|
+
// @ts-ignore
|
|
258
233
|
return fileSystemInfoEntry;
|
|
259
234
|
};
|
|
235
|
+
|
|
260
236
|
/**
|
|
261
237
|
* @param {string} filename
|
|
262
238
|
* @param {null | FileSystemInfoEntry | "ignore" | undefined} fileSystemInfoEntry
|
|
263
239
|
* @returns {boolean}
|
|
264
240
|
*/
|
|
265
|
-
|
|
266
|
-
|
|
267
241
|
const hasFileChanged = (filename, fileSystemInfoEntry) => {
|
|
268
242
|
const prevTimestamp = getTimestamps(this.prevTimestamps.get(filename));
|
|
269
243
|
const timestamp = getTimestamps(fileSystemInfoEntry);
|
|
270
244
|
return (prevTimestamp || this.startTime) < (timestamp || Infinity);
|
|
271
245
|
};
|
|
272
|
-
|
|
273
246
|
const changedFiles = [];
|
|
274
|
-
|
|
275
247
|
for (const [filename, timestamp] of fileTimestamps.entries()) {
|
|
276
248
|
if (hasFileChanged(filename, timestamp)) {
|
|
277
249
|
changedFiles.push(filename);
|
|
278
250
|
}
|
|
279
251
|
}
|
|
280
|
-
|
|
281
252
|
this.prevTimestamps = fileTimestamps;
|
|
282
253
|
return changedFiles;
|
|
283
254
|
}
|
|
284
|
-
|
|
285
255
|
}
|
|
286
|
-
|
|
287
256
|
module.exports = StylelintWebpackPlugin;
|