Skip to content

Commit

Permalink
fix: performance (#236)
Browse files Browse the repository at this point in the history
* fix: hooks to lint files

* fix: add `output.path` to default exclude paths

* chore: use `globby`

* ci: disable `npm run security`
  • Loading branch information
ricardogobbosouza authored Jun 21, 2021
1 parent 19851d6 commit ea7eadb
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 89 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ jobs:
- name: Lint
run: npm run lint

- name: Security audit
run: npm run security
#- name: Security audit
# run: npm run security

- name: Check commit message
uses: wagoid/commitlint-github-action@v1
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ A string indicating the root of your files.
### `exclude`

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

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

Expand Down
6 changes: 3 additions & 3 deletions declarations/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ declare class StylelintWebpackPlugin {
*/
getContext(compiler: Compiler): string;
/**
* @param {string[]} glob
* @param {Compiler} compiler
* @param {Module} module
* @param {string[]} wanted
* @param {string[]} exclude
* @returns {string[]}
*/
getFiles(glob: string[], compiler: Compiler, module: Module): string[];
getFiles(compiler: Compiler, wanted: string[], exclude: string[]): string[];
/**
* @param {Map<string, null | FileSystemInfoEntry | "ignore">} fileTimestamps
* @returns {string[]}
Expand Down
7 changes: 5 additions & 2 deletions declarations/utils.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
/**
* @param {string|string[]} files
* @param {string|(string|undefined)[]} files
* @param {string} context
* @returns {string[]}
*/
export function parseFiles(files: string | string[], context: string): string[];
export function parseFiles(
files: string | (string | undefined)[],
context: string
): string[];
/**
* @param {string|string[]} patterns
* @param {string|string[]} extensions
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
"dependencies": {
"@types/stylelint": "^13.13.0",
"arrify": "^2.0.1",
"fast-glob": "^3.2.5",
"jest-worker": "^27.0.2",
"globby": "^11.0.4",
"micromatch": "^4.0.4",
"normalize-path": "^3.0.0",
"schema-utils": "^3.0.0"
Expand Down
96 changes: 28 additions & 68 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isAbsolute, join } from 'path';
// @ts-ignore
import arrify from 'arrify';
// @ts-ignore
import fastGlob from 'fast-glob';
import globby from 'globby';
import { isMatch } from 'micromatch';

import { getOptions } from './options';
Expand Down Expand Up @@ -73,16 +73,19 @@ class StylelintWebpackPlugin {
const context = this.getContext(compiler);
const options = {
...this.options,
exclude: parseFiles(this.options.exclude || [], context),
exclude: parseFiles(
this.options.exclude || [
'**/node_modules/**',
compiler.options.output.path,
],
context
),
extensions: arrify(this.options.extensions),
files: parseFiles(this.options.files || '', context),
};

const wanted = parseFoldersToGlobs(options.files, options.extensions);
const exclude = parseFoldersToGlobs(
this.options.exclude ? options.exclude : '**/node_modules/**',
[]
);
const exclude = parseFoldersToGlobs(options.exclude);

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

/** @type {string[]} */
const files = [];

// Add the file to be linted
compilation.hooks.succeedModule.tap(this.key, (module) => {
const filteredFiles = this.getFiles(wanted, compiler, module).filter(
(file) =>
!files.includes(file) &&
isMatch(file, wanted, { dot: true }) &&
!isMatch(file, exclude, { dot: true })
);

for (const file of filteredFiles) {
files.push(file);
compilation.hooks.finishModules.tap(this.key, () => {
const files = this.getFiles(compiler, wanted, exclude);

if (threads > 1) {
if (threads > 1) {
for (const file of files) {
lint(parseFiles(file, context));
}
}
});

// Lint all files added
compilation.hooks.finishModules.tap(this.key, () => {
if (files.length > 0 && threads <= 1) {
} else if (files.length > 0) {
lint(parseFiles(files, context));
}
});
Expand Down Expand Up @@ -174,60 +161,33 @@ class StylelintWebpackPlugin {
}

/**
* @param {string[]} glob
* @param {Compiler} compiler
* @param {Module} module
* @param {string[]} wanted
* @param {string[]} exclude
* @returns {string[]}
*/
// eslint-disable-next-line no-unused-vars
getFiles(glob, compiler, module) {
// TODO: how to get module dependencies on css files?
// maybe implemented on next major version v3
// Temporaly lint all css files on start webpack
// on watch lint only modified files
// on webpack 5 not safe to use `module.buildInfo.snapshot`
// on webpack `module.buildInfo.fileDependencies` not working correclty

// webpack 5
/*
if (
module.buildInfo &&
module.buildInfo.snapshot &&
module.buildInfo.snapshot.fileTimestamps
) {
files = this.getChangedFiles(module.buildInfo.snapshot.fileTimestamps);
}
// webpack 4
else if (module.buildInfo && module.buildInfo.fileDependencies) {
files = Array.from(module.buildInfo.fileDependencies);
if (compiler.fileTimestamps && compiler.fileTimestamps.size > 0) {
const fileDependencies = new Map();
for (const [filename, timestamp] of compiler.fileTimestamps.entries()) {
if (files.includes(filename)) {
fileDependencies.set(filename, timestamp);
}
}
files = this.getChangedFiles(fileDependencies);
}
}
*/

getFiles(compiler, wanted, exclude) {
// webpack 5
if (compiler.modifiedFiles) {
return Array.from(compiler.modifiedFiles);
return Array.from(compiler.modifiedFiles).filter(
(file) =>
isMatch(file, wanted, { dot: true }) &&
!isMatch(file, exclude, { dot: true })
);
}

// webpack 4
/* istanbul ignore next */
if (compiler.fileTimestamps && compiler.fileTimestamps.size > 0) {
return this.getChangedFiles(compiler.fileTimestamps);
return this.getChangedFiles(compiler.fileTimestamps).filter(
(file) =>
isMatch(file, wanted, { dot: true }) &&
!isMatch(file, exclude, { dot: true })
);
}

return fastGlob.sync(glob, { dot: true });
return globby.sync(wanted, { dot: true, ignore: exclude });
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import normalizePath from 'normalize-path';
import arrify from 'arrify';

/**
* @param {string|string[]} files
* @param {string|(string|undefined)[]} files
* @param {string} context
* @returns {string[]}
*/
export function parseFiles(files, context) {
return arrify(files).map((/** @type {string} */ file) =>
normalizePath(resolve(context, file))
);
return arrify(files)
.filter((/** @type {string} */ file) => typeof file === 'string')
.map((/** @type {string} */ file) => normalizePath(resolve(context, file)));
}

/**
Expand Down

0 comments on commit ea7eadb

Please sign in to comment.