stylelint-webpack-plugin 5.0.1 → 5.1.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/README.md CHANGED
@@ -12,9 +12,9 @@
12
12
 
13
13
  # stylelint-webpack-plugin
14
14
 
15
- > This version of stylelint-webpack-plugin only works with webpack 5. For the webpack 4, see the [2.x branch](https://github.com/webpack-contrib/stylelint-webpack-plugin/tree/2.x).
15
+ > This version of `stylelint-webpack-plugin` only works with webpack 5. For webpack 4, see the [2.x branch](https://github.com/webpack/stylelint-webpack-plugin/tree/2.x).
16
16
 
17
- This plugin uses [`stylelint`](https://stylelint.io/) that helps you avoid errors and enforce conventions in your styles.
17
+ This plugin uses [`stylelint`](https://stylelint.io/), which helps you avoid errors and enforce conventions in your styles.
18
18
 
19
19
  ## Getting Started
20
20
 
@@ -36,7 +36,7 @@ or
36
36
  pnpm add -D stylelint-webpack-plugin
37
37
  ```
38
38
 
39
- > **Note**:
39
+ > [!NOTE]
40
40
  >
41
41
  > You also need to install `stylelint >= 13` from npm, if you haven't already:
42
42
 
@@ -56,14 +56,14 @@ or
56
56
  pnpm add -D stylelint
57
57
  ```
58
58
 
59
- > **Note**:
59
+ > [!NOTE]
60
60
  >
61
- > If you are using Stylelint 13 rather than 14+, you might also need to install `@types/stylelint` as a dev dependency if getting stylelint related type errors.
61
+ > If you are using Stylelint 13 rather than 14+, you might also need to install `@types/stylelint` as a dev dependency if you encounter Stylelint-related type errors.
62
62
 
63
- Then add the plugin to your webpack config. For example:
63
+ Then add the plugin to your webpack configuration. For example:
64
64
 
65
65
  ```js
66
- const StylelintPlugin = require('stylelint-webpack-plugin');
66
+ const StylelintPlugin = require("stylelint-webpack-plugin");
67
67
 
68
68
  module.exports = {
69
69
  // ...
@@ -74,7 +74,7 @@ module.exports = {
74
74
 
75
75
  ## Options
76
76
 
77
- See [stylelint's options](https://stylelint.io/user-guide/usage/node-api#options) for the complete list of options available. These options are passed through to the `stylelint` directly.
77
+ See [stylelint's options](https://stylelint.io/user-guide/usage/node-api#options) for the complete list of available options . These options are passed directly to `stylelint`.
78
78
 
79
79
  ### `cache`
80
80
 
@@ -98,7 +98,7 @@ type cacheLocation = string;
98
98
 
99
99
  - Default: `node_modules/.cache/stylelint-webpack-plugin/.stylelintcache`
100
100
 
101
- Specify the path to the cache location. Can be a file or a directory.
101
+ Specify the path to the cache location. This can be a file or a directory.
102
102
 
103
103
  ### `configFile`
104
104
 
@@ -133,7 +133,7 @@ A string indicating the root of your files.
133
133
  - Type:
134
134
 
135
135
  ```ts
136
- type exclude = string | Array<string>;
136
+ type exclude = string | string[];
137
137
  ```
138
138
 
139
139
  - Default: `['node_modules', compiler.options.output.path]`
@@ -145,24 +145,24 @@ Specify the files and/or directories to exclude. Must be relative to `options.co
145
145
  - Type:
146
146
 
147
147
  ```ts
148
- type extensions = string | Array<string>;
148
+ type extensions = string | string[];
149
149
  ```
150
150
 
151
151
  - Default: `['css', 'scss', 'sass']`
152
152
 
153
- Specify extensions that should be checked.
153
+ Specify the extensions that should be checked.
154
154
 
155
155
  ### `files`
156
156
 
157
157
  - Type:
158
158
 
159
159
  ```ts
160
- type files = string | Array<string>;
160
+ type files = string | string[];
161
161
  ```
162
162
 
163
163
  - Default: `null`
164
164
 
165
- Specify directories, files, or globs. Must be relative to `options.context`. Directories are traversed recursively looking for files matching `options.extensions`. File and glob patterns ignore `options.extensions`.
165
+ Specify directories, files, or globs. Must be relative to `options.context`. Directories are traversed recursively, looking for files matching `options.extensions`. File and glob patterns ignore `options.extensions`.
166
166
 
167
167
  ### `fix`
168
168
 
@@ -181,14 +181,14 @@ If `true`, `stylelint` will fix as many errors as possible. The fixes are made t
181
181
  - Type:
182
182
 
183
183
  ```ts
184
- type formatter = string | (
185
- results: Array<import('stylelint').LintResult>
186
- ) => string
184
+ type formatter =
185
+ | string
186
+ | ((results: import("stylelint").LintResult[]) => string);
187
187
  ```
188
188
 
189
189
  - Default: `'string'`
190
190
 
191
- Specify the formatter that you would like to use to format your results. See [formatter option](https://stylelint.io/user-guide/usage/options#formatter).
191
+ Specify the formatter you would like to use to format your results. See the [formatter option](https://stylelint.io/user-guide/usage/options#formatter).
192
192
 
193
193
  ### `lintDirtyModulesOnly`
194
194
 
@@ -200,7 +200,7 @@ type lintDirtyModulesOnly = boolean;
200
200
 
201
201
  - Default: `false`
202
202
 
203
- Lint only changed files, skip lint on start.
203
+ Lint only changed files; skip linting on start.
204
204
 
205
205
  ### `stylelintPath`
206
206
 
@@ -224,12 +224,15 @@ type threads = boolean | number;
224
224
 
225
225
  - Default: `false`
226
226
 
227
- Set to true for an auto-selected pool size based on number of cpus. Set to a number greater than 1 to set an explicit pool size. Set to false, 1, or less to disable and only run in main process.
227
+ Set to `true` for an auto-selected pool size based on number of CPUs. Set to a number greater than 1 to set an explicit pool size.
228
+
229
+ Set to `false`, 1, or less to disable and run only in main process.
228
230
 
229
231
  ### Errors and Warning
230
232
 
231
- **By default the plugin will auto adjust error reporting depending on stylelint errors/warnings counts.**
232
- You can still force this behavior by using `emitError` **or** `emitWarning` options:
233
+ **By default, the plugin will automatically adjust error reporting depending on the number of Stylelint errors/warnings.**
234
+
235
+ You can still force this behavior by using the `emitError` **or** `emitWarning` options:
233
236
 
234
237
  #### `emitError`
235
238
 
@@ -241,7 +244,7 @@ type emitError = boolean;
241
244
 
242
245
  - Default: `true`
243
246
 
244
- The errors found will always be emitted, to disable set to `false`.
247
+ The errors found will always be emitted. To disable, set to `false`.
245
248
 
246
249
  #### `emitWarning`
247
250
 
@@ -253,7 +256,7 @@ type emitWarning = boolean;
253
256
 
254
257
  - Default: `true`
255
258
 
256
- The warnings found will always be emitted, to disable set to `false`.
259
+ The warnings found will always be emitted. To disable, set to `false`.
257
260
 
258
261
  #### `failOnError`
259
262
 
@@ -265,7 +268,7 @@ type failOnError = boolean;
265
268
 
266
269
  - Default: `true`
267
270
 
268
- Will cause the module build to fail if there are any errors, to disable set to `false`.
271
+ Will cause the module build to fail if there are any errors. To disable, set to `false`.
269
272
 
270
273
  #### `failOnWarning`
271
274
 
@@ -277,7 +280,7 @@ type failOnWarning = boolean;
277
280
 
278
281
  - Default: `false`
279
282
 
280
- Will cause the module build to fail if there are any warnings, if set to `true`.
283
+ Will cause the module build to fail if there are any warnings, when set to `true`.
281
284
 
282
285
  #### `quiet`
283
286
 
@@ -289,7 +292,7 @@ type quiet = boolean;
289
292
 
290
293
  - Default: `false`
291
294
 
292
- Will process and report errors only and ignore warnings, if set to `true`.
295
+ Will process and report errors only, and ignore warnings, when set to `true`.
293
296
 
294
297
  #### `outputReport`
295
298
 
@@ -301,31 +304,37 @@ type outputReport =
301
304
  | {
302
305
  filePath?: string | undefined;
303
306
  formatter?:
304
- | (
305
- | string
306
- | ((results: Array<import('stylelint').LintResult>) => string)
307
- )
307
+ | (string | ((results: import("stylelint").LintResult[]) => string))
308
308
  | undefined;
309
309
  };
310
310
  ```
311
311
 
312
312
  - Default: `false`
313
313
 
314
- Write the output of the errors to a file, for example a `json` file for use for reporting.
314
+ Writes the output of the errors to a file - for example, a `json` file for use for reporting.
315
+
315
316
  The `filePath` is relative to the webpack config: `output.path`.
316
- You can pass in a different formatter for the output file, if none is passed in the default/configured formatter will be used.
317
+
318
+ You can pass in a different formatter for the output file. If none is passed in the default/configured formatter will be used.
317
319
 
318
320
  ```js
319
- {
320
- filePath: 'path/to/file';
321
- formatter: 'json';
322
- }
321
+ const outputReport = {
322
+ filePath: "path/to/file",
323
+ formatter: "json",
324
+ };
323
325
  ```
324
326
 
325
327
  ## Changelog
326
328
 
327
329
  [Changelog](CHANGELOG.md)
328
330
 
331
+ ## Contributing
332
+
333
+ We welcome all contributions!
334
+ If you're new here, please take a moment to review our contributing guidelines before submitting issues or pull requests.
335
+
336
+ [CONTRIBUTING](https://github.com/webpack/stylelint-webpack-plugin?tab=contributing-ov-file#contributing)
337
+
329
338
  ## License
330
339
 
331
340
  [MIT](./LICENSE)
@@ -334,10 +343,10 @@ You can pass in a different formatter for the output file, if none is passed in
334
343
  [npm-url]: https://npmjs.com/package/stylelint-webpack-plugin
335
344
  [node]: https://img.shields.io/node/v/stylelint-webpack-plugin.svg
336
345
  [node-url]: https://nodejs.org
337
- [tests]: https://github.com/webpack-contrib/stylelint-webpack-plugin/workflows/stylelint-webpack-plugin/badge.svg
338
- [tests-url]: https://github.com/webpack-contrib/stylelint-webpack-plugin/actions
339
- [cover]: https://codecov.io/gh/webpack-contrib/stylelint-webpack-plugin/branch/master/graph/badge.svg
340
- [cover-url]: https://codecov.io/gh/webpack-contrib/stylelint-webpack-plugin
346
+ [tests]: https://github.com/webpack/stylelint-webpack-plugin/workflows/stylelint-webpack-plugin/badge.svg
347
+ [tests-url]: https://github.com/webpack/stylelint-webpack-plugin/actions
348
+ [cover]: https://codecov.io/gh/webpack/stylelint-webpack-plugin/branch/main/graph/badge.svg
349
+ [cover-url]: https://codecov.io/gh/webpack/stylelint-webpack-plugin
341
350
  [discussion]: https://img.shields.io/github/discussions/webpack/webpack
342
351
  [discussion-url]: https://github.com/webpack/webpack/discussions
343
352
  [size]: https://packagephobia.now.sh/badge?p=stylelint-webpack-plugin
@@ -2,12 +2,12 @@
2
2
 
3
3
  class StylelintError extends Error {
4
4
  /**
5
- * @param {string=} messages
5
+ * @param {string=} messages messages
6
6
  */
7
7
  constructor(messages) {
8
8
  super(`[stylelint] ${messages}`);
9
- this.name = 'StylelintError';
10
- this.stack = '';
9
+ this.name = "StylelintError";
10
+ this.stack = "";
11
11
  }
12
12
  }
13
13
  module.exports = StylelintError;
@@ -2,24 +2,23 @@
2
2
 
3
3
  const {
4
4
  cpus
5
- } = require('os');
5
+ } = require("node:os");
6
6
  const {
7
7
  Worker: JestWorker
8
- } = require('jest-worker');
9
-
10
- // @ts-ignore
8
+ } = require("jest-worker");
11
9
  const {
12
- setup,
13
- lintFiles
14
- } = require('./worker');
10
+ getStylelintOptions
11
+ } = require("./options");
15
12
  const {
16
13
  jsonStringifyReplacerSortKeys
17
- } = require('./utils');
14
+ } = require("./utils");
18
15
  const {
19
- getStylelintOptions
20
- } = require('./options');
16
+ getStylelint: getStylelintInstance,
17
+ lintFiles,
18
+ setup
19
+ } = require("./worker");
21
20
 
22
- /** @type {{[key: string]: any}} */
21
+ /** @type {{ [key: string]: Linter }} */
23
22
  const cache = {};
24
23
 
25
24
  /** @typedef {{lint: (options: LinterOptions) => Promise<LinterResult>, formatters: { [k: string]: Formatter }}} Stylelint */
@@ -28,21 +27,22 @@ const cache = {};
28
27
  /** @typedef {import('stylelint').LinterResult} LinterResult */
29
28
  /** @typedef {import('stylelint').Formatter} Formatter */
30
29
  /** @typedef {import('stylelint').FormatterType} FormatterType */
30
+ /** @typedef {import('stylelint').RuleMeta} RuleMeta */
31
31
  /** @typedef {import('./options').Options} Options */
32
32
  /** @typedef {() => Promise<void>} AsyncTask */
33
33
  /** @typedef {(files: string|string[]) => Promise<LintResult[]>} LintTask */
34
- /** @typedef {{stylelint: Stylelint, lintFiles: LintTask, cleanup: AsyncTask, threads: number }} Linter */
34
+ /** @typedef {{getStylelint: () => Promise<Stylelint>, lintFiles: LintTask, cleanup: AsyncTask, threads: number }} Linter */
35
35
  /** @typedef {JestWorker & {lintFiles: LintTask}} Worker */
36
36
 
37
37
  /**
38
- * @param {Options} options
39
- * @returns {Linter}
38
+ * @param {Options} options linter options
39
+ * @returns {Linter} linter
40
40
  */
41
41
  function loadStylelint(options) {
42
42
  const stylelintOptions = getStylelintOptions(options);
43
- const stylelint = setup(options, stylelintOptions);
43
+ setup(options, stylelintOptions);
44
44
  return {
45
- stylelint,
45
+ getStylelint: getStylelintInstance,
46
46
  lintFiles,
47
47
  cleanup: async () => {},
48
48
  threads: 1
@@ -50,21 +50,34 @@ function loadStylelint(options) {
50
50
  }
51
51
 
52
52
  /**
53
- * @param {string|undefined} key
54
- * @param {number} poolSize
55
- * @param {Options} options
56
- * @returns {Linter}
53
+ * @param {string | undefined} key a cache key
54
+ * @param {Options} options options
55
+ * @returns {string} a stringified cache key
56
+ */
57
+ function getCacheKey(key, options) {
58
+ return JSON.stringify({
59
+ key,
60
+ options
61
+ }, jsonStringifyReplacerSortKeys);
62
+ }
63
+
64
+ /**
65
+ * @param {string|undefined} key a cache key
66
+ * @param {number} poolSize number of workers
67
+ * @param {Options} options options
68
+ * @returns {Linter} linter
57
69
  */
58
70
  function loadStylelintThreaded(key, poolSize, options) {
59
71
  const cacheKey = getCacheKey(key, options);
60
- const source = require.resolve('./worker');
72
+ const source = require.resolve("./worker");
61
73
  const workerOptions = {
62
74
  enableWorkerThreads: true,
63
75
  numWorkers: poolSize,
64
76
  setupArgs: [options, getStylelintOptions(options)]
65
77
  };
66
78
  const local = loadStylelint(options);
67
- let worker = /** @type {Worker?} */new JestWorker(source, workerOptions);
79
+ let worker = /** @type {Worker | null} */
80
+ new JestWorker(source, workerOptions);
68
81
 
69
82
  /** @type {Linter} */
70
83
  const context = {
@@ -86,15 +99,15 @@ function loadStylelintThreaded(key, poolSize, options) {
86
99
  }
87
100
 
88
101
  /**
89
- * @param {string|undefined} key
90
- * @param {Options} options
91
- * @returns {Linter}
102
+ * @param {string|undefined} key a cache key
103
+ * @param {Options} options options
104
+ * @returns {Linter} linter
92
105
  */
93
106
  function getStylelint(key, {
94
107
  threads,
95
108
  ...options
96
109
  }) {
97
- const max = typeof threads !== 'number' ? threads ? cpus().length - 1 : 1 : threads;
110
+ const max = typeof threads !== "number" ? threads ? cpus().length - 1 : 1 : threads;
98
111
  const cacheKey = getCacheKey(key, {
99
112
  threads,
100
113
  ...options
@@ -104,16 +117,4 @@ function getStylelint(key, {
104
117
  }
105
118
  return cache[cacheKey];
106
119
  }
107
-
108
- /**
109
- * @param {string|undefined} key
110
- * @param {Options} options
111
- * @returns {string}
112
- */
113
- function getCacheKey(key, options) {
114
- return JSON.stringify({
115
- key,
116
- options
117
- }, jsonStringifyReplacerSortKeys);
118
- }
119
120
  module.exports = getStylelint;
package/dist/index.js CHANGED
@@ -3,31 +3,31 @@
3
3
  const {
4
4
  isAbsolute,
5
5
  join
6
- } = require('path');
7
- const globby = require('globby');
6
+ } = require("node:path");
7
+ const globby = require("globby");
8
8
  const {
9
9
  isMatch
10
- } = require('micromatch');
10
+ } = require("micromatch");
11
+ const linter = require("./linter");
11
12
  const {
12
13
  getOptions
13
- } = require('./options');
14
- const linter = require('./linter');
14
+ } = require("./options");
15
15
  const {
16
16
  arrify,
17
17
  parseFiles,
18
18
  parseFoldersToGlobs
19
- } = require('./utils');
19
+ } = require("./utils");
20
20
 
21
21
  /** @typedef {import('webpack').Compiler} Compiler */
22
22
  /** @typedef {import('webpack').Module} Module */
23
23
  /** @typedef {import('./options').Options} Options */
24
- /** @typedef {Partial<{timestamp:number} | number>} FileSystemInfoEntry */
24
+ /** @typedef {Partial<{ timestamp:number } | number>} FileSystemInfoEntry */
25
25
 
26
- const STYLELINT_PLUGIN = 'StylelintWebpackPlugin';
26
+ const STYLELINT_PLUGIN = "StylelintWebpackPlugin";
27
27
  let counter = 0;
28
28
  class StylelintWebpackPlugin {
29
29
  /**
30
- * @param {Options} options
30
+ * @param {Options=} options options
31
31
  */
32
32
  constructor(options = {}) {
33
33
  this.key = STYLELINT_PLUGIN;
@@ -38,7 +38,7 @@ class StylelintWebpackPlugin {
38
38
  }
39
39
 
40
40
  /**
41
- * @param {Compiler} compiler
41
+ * @param {Compiler} compiler compiler
42
42
  * @returns {void}
43
43
  */
44
44
  apply(compiler) {
@@ -46,13 +46,13 @@ class StylelintWebpackPlugin {
46
46
  // this differentiates one from the other when being cached.
47
47
  this.key = compiler.name || `${this.key}_${counter += 1}`;
48
48
  const context = this.getContext(compiler);
49
- const excludeDefault = ['**/node_modules/**', String(compiler.options.output.path)];
49
+ const excludeDefault = ["**/node_modules/**", String(compiler.options.output.path)];
50
50
  const options = {
51
51
  ...this.options,
52
52
  context,
53
53
  exclude: parseFiles(this.options.exclude || excludeDefault, context),
54
54
  extensions: arrify(this.options.extensions),
55
- files: parseFiles(this.options.files || '', context)
55
+ files: parseFiles(this.options.files || "", context)
56
56
  };
57
57
  const wanted = parseFoldersToGlobs(options.files, options.extensions);
58
58
  const exclude = parseFoldersToGlobs(options.exclude);
@@ -60,57 +60,39 @@ class StylelintWebpackPlugin {
60
60
  // If `lintDirtyModulesOnly` is disabled,
61
61
  // execute the linter on the build
62
62
  if (!this.options.lintDirtyModulesOnly) {
63
- compiler.hooks.run.tapPromise(this.key, c => this.run(c, options, wanted, exclude));
63
+ compiler.hooks.run.tapPromise(this.key, compiler => this.run(compiler, options, wanted, exclude));
64
64
  }
65
- let isFirstRun = this.options.lintDirtyModulesOnly;
66
- compiler.hooks.watchRun.tapPromise(this.key, c => {
67
- if (isFirstRun) {
68
- isFirstRun = false;
65
+ let hasCompilerRunByDirtyModule = this.options.lintDirtyModulesOnly;
66
+ compiler.hooks.watchRun.tapPromise(this.key, compiler => {
67
+ if (hasCompilerRunByDirtyModule) {
68
+ hasCompilerRunByDirtyModule = false;
69
69
  return Promise.resolve();
70
70
  }
71
- return this.run(c, options, wanted, exclude);
71
+ return this.run(compiler, options, wanted, exclude);
72
72
  });
73
73
  }
74
74
 
75
75
  /**
76
- * @param {Compiler} compiler
77
- * @param {Options} options
78
- * @param {string[]} wanted
79
- * @param {string[]} exclude
76
+ * @param {Compiler} compiler compiler
77
+ * @param {Options} options options
78
+ * @param {string[]} wanted wanted files
79
+ * @param {string[]} exclude exclude files
80
80
  */
81
81
  async run(compiler, options, wanted, exclude) {
82
82
  // Do not re-hook
83
- /* istanbul ignore if */
84
- if (
85
- // @ts-ignore
86
- compiler.hooks.thisCompilation.taps.find(({
83
+ const isCompilerHooked = compiler.hooks.thisCompilation.taps.find(({
87
84
  name
88
- }) => name === this.key)) {
89
- return;
90
- }
85
+ }) => name === this.key);
86
+ if (isCompilerHooked) return;
91
87
  compiler.hooks.thisCompilation.tap(this.key, compilation => {
92
- /** @type {import('./linter').Linter} */
93
- let lint;
94
-
95
- /** @type {import('./linter').Reporter} */
96
- let report;
97
-
98
- /** @type number */
99
- let threads;
100
- try {
101
- ({
102
- lint,
103
- report,
104
- threads
105
- } = linter(this.key, options, compilation));
106
- } catch (e) {
107
- compilation.errors.push(e);
108
- return;
109
- }
88
+ const {
89
+ lint,
90
+ report,
91
+ threads
92
+ } = linter(this.key, options, compilation);
110
93
  compilation.hooks.finishModules.tapPromise(this.key, async () => {
111
94
  /** @type {string[]} */
112
- // @ts-ignore
113
- const files = compiler.modifiedFiles ? Array.from(compiler.modifiedFiles).filter(file => isMatch(file, wanted, {
95
+ const files = compiler.modifiedFiles ? [...compiler.modifiedFiles].filter(file => isMatch(file, wanted, {
114
96
  dot: true
115
97
  }) && !isMatch(file, exclude, {
116
98
  dot: true
@@ -127,8 +109,9 @@ class StylelintWebpackPlugin {
127
109
  }
128
110
  });
129
111
 
130
- // await and interpret results
131
- compilation.hooks.additionalAssets.tapPromise(this.key, processResults);
112
+ /**
113
+ * @returns {Promise<void>}
114
+ */
132
115
  async function processResults() {
133
116
  const {
134
117
  errors,
@@ -136,30 +119,28 @@ class StylelintWebpackPlugin {
136
119
  generateReportAsset
137
120
  } = await report();
138
121
  if (warnings && !options.failOnWarning) {
139
- // @ts-ignore
140
122
  compilation.warnings.push(warnings);
141
123
  } else if (warnings && options.failOnWarning) {
142
- // @ts-ignore
143
124
  compilation.errors.push(warnings);
144
125
  }
145
126
  if (errors && options.failOnError) {
146
- // @ts-ignore
147
127
  compilation.errors.push(errors);
148
128
  } else if (errors && !options.failOnError) {
149
- // @ts-ignore
150
129
  compilation.warnings.push(errors);
151
130
  }
152
131
  if (generateReportAsset) {
153
132
  await generateReportAsset(compilation);
154
133
  }
155
134
  }
135
+
136
+ // await and interpret results
137
+ compilation.hooks.additionalAssets.tapPromise(this.key, processResults);
156
138
  });
157
139
  }
158
140
 
159
141
  /**
160
- *
161
- * @param {Compiler} compiler
162
- * @returns {string}
142
+ * @param {Compiler} compiler compiler
143
+ * @returns {string} context
163
144
  */
164
145
  getContext(compiler) {
165
146
  if (!this.options.context) {