Skip to content

Commit ea7eadb

Browse files
fix: performance (#236)
* fix: hooks to lint files * fix: add `output.path` to default exclude paths * chore: use `globby` * ci: disable `npm run security`
1 parent 19851d6 commit ea7eadb

File tree

8 files changed

+52
-89
lines changed

8 files changed

+52
-89
lines changed

.github/workflows/nodejs.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ jobs:
4343
- name: Lint
4444
run: npm run lint
4545

46-
- name: Security audit
47-
run: npm run security
46+
#- name: Security audit
47+
# run: npm run security
4848

4949
- name: Check commit message
5050
uses: wagoid/commitlint-github-action@v1

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ A string indicating the root of your files.
6464
### `exclude`
6565

6666
- Type: `String|Array[String]`
67-
- Default: `'node_modules'`
67+
- Default: `['node_modules', compiler.options.output.path]`
6868

6969
Specify the files and/or directories to exclude. Must be relative to `options.context`.
7070

declarations/index.d.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ declare class StylelintWebpackPlugin {
3333
*/
3434
getContext(compiler: Compiler): string;
3535
/**
36-
* @param {string[]} glob
3736
* @param {Compiler} compiler
38-
* @param {Module} module
37+
* @param {string[]} wanted
38+
* @param {string[]} exclude
3939
* @returns {string[]}
4040
*/
41-
getFiles(glob: string[], compiler: Compiler, module: Module): string[];
41+
getFiles(compiler: Compiler, wanted: string[], exclude: string[]): string[];
4242
/**
4343
* @param {Map<string, null | FileSystemInfoEntry | "ignore">} fileTimestamps
4444
* @returns {string[]}

declarations/utils.d.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
/**
2-
* @param {string|string[]} files
2+
* @param {string|(string|undefined)[]} files
33
* @param {string} context
44
* @returns {string[]}
55
*/
6-
export function parseFiles(files: string | string[], context: string): string[];
6+
export function parseFiles(
7+
files: string | (string | undefined)[],
8+
context: string
9+
): string[];
710
/**
811
* @param {string|string[]} patterns
912
* @param {string|string[]} extensions

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
"dependencies": {
4949
"@types/stylelint": "^13.13.0",
5050
"arrify": "^2.0.1",
51-
"fast-glob": "^3.2.5",
5251
"jest-worker": "^27.0.2",
52+
"globby": "^11.0.4",
5353
"micromatch": "^4.0.4",
5454
"normalize-path": "^3.0.0",
5555
"schema-utils": "^3.0.0"

src/index.js

Lines changed: 28 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { isAbsolute, join } from 'path';
33
// @ts-ignore
44
import arrify from 'arrify';
55
// @ts-ignore
6-
import fastGlob from 'fast-glob';
6+
import globby from 'globby';
77
import { isMatch } from 'micromatch';
88

99
import { getOptions } from './options';
@@ -73,16 +73,19 @@ class StylelintWebpackPlugin {
7373
const context = this.getContext(compiler);
7474
const options = {
7575
...this.options,
76-
exclude: parseFiles(this.options.exclude || [], context),
76+
exclude: parseFiles(
77+
this.options.exclude || [
78+
'**/node_modules/**',
79+
compiler.options.output.path,
80+
],
81+
context
82+
),
7783
extensions: arrify(this.options.extensions),
7884
files: parseFiles(this.options.files || '', context),
7985
};
8086

8187
const wanted = parseFoldersToGlobs(options.files, options.extensions);
82-
const exclude = parseFoldersToGlobs(
83-
this.options.exclude ? options.exclude : '**/node_modules/**',
84-
[]
85-
);
88+
const exclude = parseFoldersToGlobs(options.exclude);
8689

8790
compiler.hooks.thisCompilation.tap(this.key, (compilation) => {
8891
/** @type {import('./linter').Linter} */
@@ -99,30 +102,14 @@ class StylelintWebpackPlugin {
99102
return;
100103
}
101104

102-
/** @type {string[]} */
103-
const files = [];
104-
105-
// Add the file to be linted
106-
compilation.hooks.succeedModule.tap(this.key, (module) => {
107-
const filteredFiles = this.getFiles(wanted, compiler, module).filter(
108-
(file) =>
109-
!files.includes(file) &&
110-
isMatch(file, wanted, { dot: true }) &&
111-
!isMatch(file, exclude, { dot: true })
112-
);
113-
114-
for (const file of filteredFiles) {
115-
files.push(file);
105+
compilation.hooks.finishModules.tap(this.key, () => {
106+
const files = this.getFiles(compiler, wanted, exclude);
116107

117-
if (threads > 1) {
108+
if (threads > 1) {
109+
for (const file of files) {
118110
lint(parseFiles(file, context));
119111
}
120-
}
121-
});
122-
123-
// Lint all files added
124-
compilation.hooks.finishModules.tap(this.key, () => {
125-
if (files.length > 0 && threads <= 1) {
112+
} else if (files.length > 0) {
126113
lint(parseFiles(files, context));
127114
}
128115
});
@@ -174,60 +161,33 @@ class StylelintWebpackPlugin {
174161
}
175162

176163
/**
177-
* @param {string[]} glob
178164
* @param {Compiler} compiler
179-
* @param {Module} module
165+
* @param {string[]} wanted
166+
* @param {string[]} exclude
180167
* @returns {string[]}
181168
*/
182169
// eslint-disable-next-line no-unused-vars
183-
getFiles(glob, compiler, module) {
184-
// TODO: how to get module dependencies on css files?
185-
// maybe implemented on next major version v3
186-
// Temporaly lint all css files on start webpack
187-
// on watch lint only modified files
188-
// on webpack 5 not safe to use `module.buildInfo.snapshot`
189-
// on webpack `module.buildInfo.fileDependencies` not working correclty
190-
191-
// webpack 5
192-
/*
193-
if (
194-
module.buildInfo &&
195-
module.buildInfo.snapshot &&
196-
module.buildInfo.snapshot.fileTimestamps
197-
) {
198-
files = this.getChangedFiles(module.buildInfo.snapshot.fileTimestamps);
199-
}
200-
201-
// webpack 4
202-
else if (module.buildInfo && module.buildInfo.fileDependencies) {
203-
files = Array.from(module.buildInfo.fileDependencies);
204-
205-
if (compiler.fileTimestamps && compiler.fileTimestamps.size > 0) {
206-
const fileDependencies = new Map();
207-
208-
for (const [filename, timestamp] of compiler.fileTimestamps.entries()) {
209-
if (files.includes(filename)) {
210-
fileDependencies.set(filename, timestamp);
211-
}
212-
}
213-
214-
files = this.getChangedFiles(fileDependencies);
215-
}
216-
}
217-
*/
218-
170+
getFiles(compiler, wanted, exclude) {
219171
// webpack 5
220172
if (compiler.modifiedFiles) {
221-
return Array.from(compiler.modifiedFiles);
173+
return Array.from(compiler.modifiedFiles).filter(
174+
(file) =>
175+
isMatch(file, wanted, { dot: true }) &&
176+
!isMatch(file, exclude, { dot: true })
177+
);
222178
}
223179

224180
// webpack 4
225181
/* istanbul ignore next */
226182
if (compiler.fileTimestamps && compiler.fileTimestamps.size > 0) {
227-
return this.getChangedFiles(compiler.fileTimestamps);
183+
return this.getChangedFiles(compiler.fileTimestamps).filter(
184+
(file) =>
185+
isMatch(file, wanted, { dot: true }) &&
186+
!isMatch(file, exclude, { dot: true })
187+
);
228188
}
229189

230-
return fastGlob.sync(glob, { dot: true });
190+
return globby.sync(wanted, { dot: true, ignore: exclude });
231191
}
232192

233193
/**

src/utils.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import normalizePath from 'normalize-path';
77
import arrify from 'arrify';
88

99
/**
10-
* @param {string|string[]} files
10+
* @param {string|(string|undefined)[]} files
1111
* @param {string} context
1212
* @returns {string[]}
1313
*/
1414
export function parseFiles(files, context) {
15-
return arrify(files).map((/** @type {string} */ file) =>
16-
normalizePath(resolve(context, file))
17-
);
15+
return arrify(files)
16+
.filter((/** @type {string} */ file) => typeof file === 'string')
17+
.map((/** @type {string} */ file) => normalizePath(resolve(context, file)));
1818
}
1919

2020
/**

0 commit comments

Comments
 (0)