Skip to content

Commit

Permalink
fix: allow multiple instances (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardogobbosouza authored Mar 24, 2021
1 parent bb8750c commit 0cdd621
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 19 deletions.
2 changes: 1 addition & 1 deletion declarations/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ declare class ESLintWebpackPlugin {
* @param {Options} options
*/
constructor(options?: Options);
key: string;
options: import('./options').PluginOptions;
/**
* @param {Compiler} compiler
Expand All @@ -17,7 +18,6 @@ declare class ESLintWebpackPlugin {
* @returns {void}
*/
apply(compiler: Compiler): void;
key: string | undefined;
/**
*
* @param {Compiler} compiler
Expand Down
2 changes: 1 addition & 1 deletion src/cjs.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const plugin = require('./index');
const plugin = require('./');

module.exports = plugin.default;
23 changes: 9 additions & 14 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ESLintWebpackPlugin {
* @param {Options} options
*/
constructor(options = {}) {
this.key = ESLINT_PLUGIN;
this.options = getOptions(options);
this.run = this.run.bind(this);
}
Expand All @@ -30,20 +31,20 @@ class ESLintWebpackPlugin {
apply(compiler) {
// Generate key for each compilation,
// this differentiates one from the other when being cached.
this.key = compiler.name || `${ESLINT_PLUGIN}_${(counter += 1)}`;
this.key = compiler.name || `${this.key}_${(counter += 1)}`;

// If `lintDirtyModulesOnly` is disabled,
// execute the linter on the build
if (!this.options.lintDirtyModulesOnly) {
compiler.hooks.run.tapPromise(ESLINT_PLUGIN, this.run);
compiler.hooks.run.tapPromise(this.key, this.run);
}

// TODO: Figure out want `compiler.watching` is and how to use it in Webpack5.
// From my testing of compiler.watch() ... compiler.watching is always
// undefined (webpack 4 doesn't define it either) I'm leaving it out
// for now.
let isFirstRun = this.options.lintDirtyModulesOnly;
compiler.hooks.watchRun.tapPromise(ESLINT_PLUGIN, (c) => {
compiler.hooks.watchRun.tapPromise(this.key, (c) => {
if (isFirstRun) {
isFirstRun = false;

Expand All @@ -61,10 +62,7 @@ class ESLintWebpackPlugin {
// Do not re-hook
if (
// @ts-ignore
compiler.hooks.thisCompilation.taps.find(
// @ts-ignore
({ name }) => name === ESLINT_PLUGIN
)
compiler.hooks.thisCompilation.taps.find(({ name }) => name === this.key)
) {
return;
}
Expand All @@ -85,7 +83,7 @@ class ESLintWebpackPlugin {
[]
);

compiler.hooks.thisCompilation.tap(ESLINT_PLUGIN, (compilation) => {
compiler.hooks.thisCompilation.tap(this.key, (compilation) => {
/** @type {import('./linter').Linter} */
let lint;
/** @type {import('./linter').Reporter} */
Expand All @@ -103,7 +101,7 @@ class ESLintWebpackPlugin {

// @ts-ignore
// Add the file to be linted
compilation.hooks.succeedModule.tap(ESLINT_PLUGIN, ({ resource }) => {
compilation.hooks.succeedModule.tap(this.key, ({ resource }) => {
if (resource) {
const [file] = resource.split('?');

Expand All @@ -119,17 +117,14 @@ class ESLintWebpackPlugin {
});

// Lint all files added
compilation.hooks.finishModules.tap(ESLINT_PLUGIN, () => {
compilation.hooks.finishModules.tap(this.key, () => {
if (files.length > 0) {
lint(files);
}
});

// await and interpret results
compilation.hooks.additionalAssets.tapPromise(
ESLINT_PLUGIN,
processResults
);
compilation.hooks.additionalAssets.tapPromise(this.key, processResults);

async function processResults() {
const { errors, warnings, generateReportAsset } = await report();
Expand Down
4 changes: 2 additions & 2 deletions test/empty.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { join } from 'path';

import webpack from 'webpack';

import ESLintPlugin from '../src/index';
import ESLintPlugin from '../src';

describe('empty', () => {
it('no error when no files matching', (done) => {
const compiler = webpack({
context: join(__dirname, 'fixtures', 'empty'),
mode: 'development',
entry: '../index',
entry: '../',
plugins: [new ESLintPlugin()],
});

Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/multiple-entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require('./good');
require('./error');
65 changes: 65 additions & 0 deletions test/multiple-instances.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import ESLintPlugin from '../src';

import pack from './utils/pack';

describe('multiple instances', () => {
it("should don't fail", (done) => {
const compiler = pack(
'multiple',
{},
{
plugins: [
new ESLintPlugin({ ignore: false, exclude: 'error.js' }),
new ESLintPlugin({ ignore: false, exclude: 'error.js' }),
],
}
);

compiler.run((err, stats) => {
expect(err).toBeNull();
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(false);
done();
});
});

it('should fail on first instance', (done) => {
const compiler = pack(
'multiple',
{},
{
plugins: [
new ESLintPlugin({ ignore: false, exclude: 'good.js' }),
new ESLintPlugin({ ignore: false, exclude: 'error.js' }),
],
}
);

compiler.run((err, stats) => {
expect(err).toBeNull();
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(true);
done();
});
});

it('should fail on second instance', (done) => {
const compiler = pack(
'multiple',
{},
{
plugins: [
new ESLintPlugin({ ignore: false, exclude: 'error.js' }),
new ESLintPlugin({ ignore: false, exclude: 'good.js' }),
],
}
);

compiler.run((err, stats) => {
expect(err).toBeNull();
expect(stats.hasWarnings()).toBe(false);
expect(stats.hasErrors()).toBe(true);
done();
});
});
});
2 changes: 1 addition & 1 deletion test/utils/conf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { join } from 'path';

import ESLintPlugin from '../../src/index';
import ESLintPlugin from '../../src';

export default (entry, pluginConf = {}, webpackConf = {}) => {
const testDir = join(__dirname, '..');
Expand Down

0 comments on commit 0cdd621

Please sign in to comment.