Skip to content

Commit 19fa551

Browse files
perf: use finishModules (#73)
* perf: use `finishModules` * chore: update deps * style: formatting * test: add test to perf for hook `finishModules` * test: add more tests * refactor: finishModules * refactor: finishModules * perf: use for
1 parent 8a72a8a commit 19fa551

15 files changed

+1080
-1883
lines changed

declarations/ESLintError.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
export default class ESLintError extends WebpackError {
1+
export default class ESLintError {
22
/**
33
* @param {string=} messages
44
*/
55
constructor(messages?: string | undefined);
6+
name: string;
7+
stack: string;
68
}
7-
import { WebpackError } from 'webpack';

declarations/cjs.d.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
declare const _exports: typeof import('.').default;
1+
declare const _exports: typeof plugin.default;
22
export = _exports;
3+
import plugin = require('.');

declarations/linter.d.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ export type GenerateReport = (compilation: Compilation) => Promise<void>;
2828
export type Report = {
2929
errors?: ESLintError | undefined;
3030
warnings?: ESLintError | undefined;
31-
generateReportAsset?:
32-
| ((compilation: Compilation) => Promise<void>)
33-
| undefined;
31+
generateReportAsset?: GenerateReport | undefined;
3432
};
3533
export type Reporter = () => Promise<Report>;
3634
export type Linter = (files: string | string[]) => void;

package-lock.json

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

package.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,40 +46,40 @@
4646
"webpack": "^4.0.0 || ^5.0.0"
4747
},
4848
"dependencies": {
49-
"@types/eslint": "^7.2.4",
49+
"@types/eslint": "^7.2.6",
5050
"arrify": "^2.0.1",
5151
"jest-worker": "^26.6.2",
5252
"micromatch": "^4.0.2",
5353
"schema-utils": "^3.0.0"
5454
},
5555
"devDependencies": {
56-
"@babel/cli": "^7.12.1",
57-
"@babel/core": "^7.12.3",
58-
"@babel/preset-env": "^7.12.1",
56+
"@babel/cli": "^7.12.10",
57+
"@babel/core": "^7.12.10",
58+
"@babel/preset-env": "^7.12.11",
5959
"@commitlint/cli": "^11.0.0",
6060
"@commitlint/config-conventional": "^11.0.0",
61-
"@types/fs-extra": "^9.0.4",
61+
"@types/fs-extra": "^9.0.6",
6262
"@types/micromatch": "^4.0.1",
63-
"@types/webpack": "^4.41.25",
63+
"@types/webpack": "^4.41.26",
6464
"@webpack-contrib/eslint-config-webpack": "^3.0.0",
6565
"babel-eslint": "^10.1.0",
6666
"babel-jest": "^26.6.3",
67-
"chokidar": "^3.4.3",
68-
"cross-env": "^7.0.2",
67+
"chokidar": "^3.5.1",
68+
"cross-env": "^7.0.3",
6969
"del": "^6.0.0",
7070
"del-cli": "^3.0.1",
71-
"eslint": "^7.13.0",
72-
"eslint-config-prettier": "^6.15.0",
71+
"eslint": "^7.19.0",
72+
"eslint-config-prettier": "^7.2.0",
7373
"eslint-plugin-import": "^2.22.1",
74-
"fs-extra": "^9.0.1",
75-
"husky": "^4.3.0",
74+
"fs-extra": "^9.1.0",
75+
"husky": "^4.3.8",
7676
"jest": "^26.6.3",
77-
"lint-staged": "^10.5.1",
77+
"lint-staged": "^10.5.3",
7878
"npm-run-all": "^4.1.5",
79-
"prettier": "^2.1.2",
80-
"standard-version": "^9.0.0",
81-
"typescript": "^4.0.5",
82-
"webpack": "^5.15.0"
79+
"prettier": "^2.2.1",
80+
"standard-version": "^9.1.0",
81+
"typescript": "^4.1.3",
82+
"webpack": "^5.19.0"
8383
},
8484
"keywords": [
8585
"eslint",

src/index.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -95,20 +95,31 @@ class ESLintWebpackPlugin {
9595
return;
9696
}
9797

98-
// @ts-ignore
99-
const processModule = (module) => {
100-
if (module.resource) {
101-
const [file] = module.resource.split('?');
98+
// Gather Files to lint
99+
compilation.hooks.finishModules.tap(ESLINT_PLUGIN, (modules) => {
100+
/** @type {string[]} */
101+
const files = [];
102102

103-
if (file && isMatch(file, wanted) && !isMatch(file, exclude)) {
104-
// Queue file for linting.
105-
lint(file);
103+
// @ts-ignore
104+
for (const { resource } of modules) {
105+
if (resource) {
106+
const [file] = resource.split('?');
107+
108+
if (
109+
file &&
110+
!files.includes(file) &&
111+
isMatch(file, wanted) &&
112+
!isMatch(file, exclude)
113+
) {
114+
files.push(file);
115+
}
106116
}
107117
}
108-
};
109118

110-
// Gather Files to lint
111-
compilation.hooks.succeedModule.tap(ESLINT_PLUGIN, processModule);
119+
if (files.length > 0) {
120+
lint(files);
121+
}
122+
});
112123

113124
// await and interpret results
114125
compilation.hooks.additionalAssets.tapPromise(

test/error.test.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ describe('error', () => {
1717
});
1818

1919
it('should propagate eslint exceptions as errors', (done) => {
20-
jest.mock('eslint', () => ({
21-
ESLint: function ESLint() {
22-
this.lintFiles = async () => Promise.reject(new Error('Oh no!'));
23-
},
24-
}));
20+
jest.mock('eslint', () => {
21+
return {
22+
ESLint: function ESLint() {
23+
this.lintFiles = async () => Promise.reject(new Error('Oh no!'));
24+
},
25+
};
26+
});
2527

2628
const compiler = pack('good', { threads: false });
2729

test/eslint-lint.test.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import pack from './utils/pack';
2+
3+
describe('eslint lint', () => {
4+
const mockLintFiles = jest.fn().mockReturnValue([]);
5+
6+
beforeAll(() => {
7+
jest.mock('eslint', () => {
8+
return {
9+
ESLint: function ESLint() {
10+
this.lintFiles = mockLintFiles;
11+
},
12+
};
13+
});
14+
});
15+
16+
beforeEach(() => {
17+
mockLintFiles.mockClear();
18+
});
19+
20+
it('should lint one file', (done) => {
21+
const compiler = pack('lint-one', { threads: false });
22+
23+
compiler.run((err) => {
24+
const files = [expect.stringMatching('lint-one-entry.js')];
25+
expect(mockLintFiles).toHaveBeenCalledWith(files);
26+
expect(err).toBeNull();
27+
done();
28+
});
29+
});
30+
31+
it('should lint two files', (done) => {
32+
const compiler = pack('lint-two', { threads: false });
33+
34+
compiler.run((err) => {
35+
const files = [
36+
expect.stringMatching('lint-two-entry.js'),
37+
expect.stringMatching('lint.js'),
38+
];
39+
expect(mockLintFiles).toHaveBeenCalledWith(files);
40+
expect(err).toBeNull();
41+
done();
42+
});
43+
});
44+
45+
it('should lint more files', (done) => {
46+
const compiler = pack('lint-more', { threads: false });
47+
48+
compiler.run((err) => {
49+
const files = [
50+
expect.stringMatching('lint-more-entry.js'),
51+
expect.stringMatching('lint-more.js'),
52+
expect.stringMatching('lint.js'),
53+
];
54+
expect(mockLintFiles).toHaveBeenCalledWith(files);
55+
expect(err).toBeNull();
56+
done();
57+
});
58+
});
59+
});

test/fixtures/lint-more-entry.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require('./lint-more')

test/fixtures/lint-more.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require('./lint')

0 commit comments

Comments
 (0)