Skip to content

Commit

Permalink
fix: threads multi-compiler (#69)
Browse files Browse the repository at this point in the history
* fix: threads multi-compiler

* fix: set key in apply
  • Loading branch information
ricardogobbosouza committed Jan 25, 2021
1 parent a67235f commit cef4f74
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 18 deletions.
13 changes: 11 additions & 2 deletions declarations/getESLint.d.ts
Expand Up @@ -11,16 +11,25 @@
*/
export function loadESLint(options: Options): Linter;
/**
* @param {string|undefined} key
* @param {number} poolSize
* @param {Options} options
* @returns {Linter}
*/
export function loadESLintThreaded(poolSize: number, options: Options): Linter;
export function loadESLintThreaded(
key: string | undefined,
poolSize: number,
options: Options
): Linter;
/**
* @param {string|undefined} key
* @param {Options} options
* @returns {Linter}
*/
export default function getESLint({ threads, ...options }: Options): Linter;
export default function getESLint(
key: string | undefined,
{ threads, ...options }: Options
): Linter;
export type ESLint = import('eslint').ESLint;
export type LintResult = import('eslint').ESLint.LintResult;
export type Options = import('./options').PluginOptions &
Expand Down
1 change: 1 addition & 0 deletions declarations/index.d.ts
Expand Up @@ -13,6 +13,7 @@ export class ESLintWebpackPlugin {
* @returns {void}
*/
apply(compiler: Compiler): void;
key: string | undefined;
/**
*
* @param {Compiler} compiler
Expand Down
2 changes: 2 additions & 0 deletions declarations/linter.d.ts
@@ -1,9 +1,11 @@
/**
* @param {string|undefined} key
* @param {Options} options
* @param {Compilation} compilation
* @returns {{lint: Linter, report: Reporter}}
*/
export default function linter(
key: string | undefined,
options: Options,
compilation: Compilation
): {
Expand Down
25 changes: 14 additions & 11 deletions src/getESLint.js
Expand Up @@ -46,12 +46,13 @@ export function loadESLint(options) {
}

/**
* @param {string|undefined} key
* @param {number} poolSize
* @param {Options} options
* @returns {Linter}
*/
export function loadESLintThreaded(poolSize, options) {
const key = getCacheKey(options);
export function loadESLintThreaded(key, poolSize, options) {
const cacheKey = getCacheKey(key, options);
const { eslintPath = 'eslint' } = options;
const source = require.resolve('./worker');
const workerOptions = {
Expand All @@ -74,7 +75,7 @@ export function loadESLintThreaded(poolSize, options) {
(worker && (await worker.lintFiles(files))) ||
/* istanbul ignore next */ [],
cleanup: async () => {
cache[key] = local;
cache[cacheKey] = local;
context.lintFiles = (files) => local.lintFiles(files);
if (worker) {
worker.end();
Expand All @@ -87,10 +88,11 @@ export function loadESLintThreaded(poolSize, options) {
}

/**
* @param {string|undefined} key
* @param {Options} options
* @returns {Linter}
*/
export default function getESLint({ threads, ...options }) {
export default function getESLint(key, { threads, ...options }) {
const max =
typeof threads !== 'number'
? threads
Expand All @@ -99,18 +101,19 @@ export default function getESLint({ threads, ...options }) {
: /* istanbul ignore next */
threads;

const key = getCacheKey({ threads, ...options });
if (!cache[key]) {
cache[key] =
max > 1 ? loadESLintThreaded(max, options) : loadESLint(options);
const cacheKey = getCacheKey(key, { threads, ...options });
if (!cache[cacheKey]) {
cache[cacheKey] =
max > 1 ? loadESLintThreaded(key, max, options) : loadESLint(options);
}
return cache[key];
return cache[cacheKey];
}

/**
* @param {string|undefined} key
* @param {Options} options
* @returns {string}
*/
function getCacheKey(options) {
return JSON.stringify(options, jsonStringifyReplacerSortKeys);
function getCacheKey(key, options) {
return JSON.stringify({ key, options }, jsonStringifyReplacerSortKeys);
}
9 changes: 8 additions & 1 deletion src/index.js
Expand Up @@ -11,6 +11,7 @@ import { parseFiles, parseFoldersToGlobs } from './utils';
/** @typedef {import('./options').Options} Options */

const ESLINT_PLUGIN = 'ESLintWebpackPlugin';
let counter = 0;

export class ESLintWebpackPlugin {
/**
Expand All @@ -26,6 +27,12 @@ export class ESLintWebpackPlugin {
* @returns {void}
*/
apply(compiler) {
// Generate key for each compilation,
// this differentiates one from the other when being cached.
this.key = compiler.name || `${ESLINT_PLUGIN}_${(counter += 1)}`;

// If `lintDirtyModulesOnly` is disabled,
// execute the linter on the build
if (!this.options.lintDirtyModulesOnly) {
compiler.hooks.run.tapPromise(ESLINT_PLUGIN, this.run);
}
Expand Down Expand Up @@ -81,7 +88,7 @@ export class ESLintWebpackPlugin {
let report;

try {
({ lint, report } = linter(options, compilation));
({ lint, report } = linter(this.key, options, compilation));
} catch (e) {
compilation.errors.push(e);
return;
Expand Down
5 changes: 3 additions & 2 deletions src/linter.js
Expand Up @@ -21,11 +21,12 @@ import getESLint from './getESLint';
const resultStorage = new WeakMap();

/**
* @param {string|undefined} key
* @param {Options} options
* @param {Compilation} compilation
* @returns {{lint: Linter, report: Reporter}}
*/
export default function linter(options, compilation) {
export default function linter(key, options, compilation) {
/** @type {ESLint} */
let eslint;

Expand All @@ -41,7 +42,7 @@ export default function linter(options, compilation) {
const crossRunResultStorage = getResultStorage(compilation);

try {
({ eslint, lintFiles, cleanup } = getESLint(options));
({ eslint, lintFiles, cleanup } = getESLint(key, options));
} catch (e) {
throw new ESLintError(e.message);
}
Expand Down
4 changes: 2 additions & 2 deletions test/threads.test.js
Expand Up @@ -6,7 +6,7 @@ import { loadESLint, loadESLintThreaded } from '../src/getESLint';
describe('Threading', () => {
test('Threaded interface should look like non-threaded interface', async () => {
const single = loadESLint({});
const threaded = loadESLintThreaded(1, {});
const threaded = loadESLintThreaded('foo', 1, {});
for (const key of Object.keys(single)) {
expect(typeof single[key]).toEqual(typeof threaded[key]);
}
Expand All @@ -21,7 +21,7 @@ describe('Threading', () => {
});

test('Threaded should lint files', async () => {
const threaded = loadESLintThreaded(1, { ignore: false });
const threaded = loadESLintThreaded('bar', 1, { ignore: false });
try {
const [good, bad] = await Promise.all([
threaded.lintFiles(join(__dirname, 'fixtures/good.js')),
Expand Down

0 comments on commit cef4f74

Please sign in to comment.