diff --git a/README.md b/README.md index b52582a..4c3c53f 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,18 @@ type exclude = string | Array; Specify the files and/or directories to exclude. Must be relative to `options.context`. +### `resourceQueryExclude` + +- Type: + +```ts +type resourceQueryExclude = RegExp | Array; +``` + +- Default: `[]` + +Specify the resource query to exclude. + ### `files` - Type: diff --git a/package-lock.json b/package-lock.json index 3bcbc25..c03261a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11147,6 +11147,7 @@ "version": "9.3.2", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz", "integrity": "sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ==", + "deprecated": "standard-version is deprecated. If you're a GitHub user, I recommend https://github.com/googleapis/release-please as an alternative.", "dev": true, "dependencies": { "chalk": "^2.4.2", diff --git a/src/index.js b/src/index.js index 96f26aa..045a727 100644 --- a/src/index.js +++ b/src/index.js @@ -38,6 +38,9 @@ class ESLintWebpackPlugin { this.getContext(compiler) ), extensions: arrify(this.options.extensions), + resourceQueryExclude: arrify(this.options.resourceQueryExclude || []).map( + (item) => (item instanceof RegExp ? item : new RegExp(item)) + ), files: parseFiles(this.options.files || '', this.getContext(compiler)), }; @@ -69,7 +72,7 @@ class ESLintWebpackPlugin { /** * @param {Compiler} compiler - * @param {Options} options + * @param {Omit & {resourceQueryExclude: RegExp[]}} options * @param {string[]} wanted * @param {string[]} exclude */ @@ -104,13 +107,14 @@ class ESLintWebpackPlugin { // Add the file to be linted compilation.hooks.succeedModule.tap(this.key, ({ resource }) => { if (resource) { - const [file] = resource.split('?'); + const [file, query] = resource.split('?'); if ( file && !files.includes(file) && isMatch(file, wanted, { dot: true }) && - !isMatch(file, exclude, { dot: true }) + !isMatch(file, exclude, { dot: true }) && + options.resourceQueryExclude.every((reg) => !reg.test(query)) ) { files.push(file); diff --git a/src/options.js b/src/options.js index 96cd58b..aac1d1b 100644 --- a/src/options.js +++ b/src/options.js @@ -36,6 +36,7 @@ const schema = require('./options.json'); * @property {boolean=} quiet * @property {OutputReport=} outputReport * @property {number|boolean=} threads + * @property {RegExp|RegExp[]=} resourceQueryExclude */ /** @typedef {PluginOptions & ESLintOptions} Options */ @@ -50,6 +51,7 @@ function getOptions(pluginOptions) { emitError: true, emitWarning: true, failOnError: true, + resourceQueryExclude: [], ...pluginOptions, ...(pluginOptions.quiet ? { emitError: true, emitWarning: false } : {}), }; diff --git a/src/options.json b/src/options.json index b006321..aa50a72 100644 --- a/src/options.json +++ b/src/options.json @@ -22,6 +22,10 @@ "description": "Specify the files and/or directories to exclude. Must be relative to `options.context`.", "anyOf": [{ "type": "string" }, { "type": "array" }] }, + "resourceQueryExclude": { + "description": "Specify the resource query to exclude.", + "anyOf": [{ "instanceof": "RegExp" }, { "type": "array" }] + }, "failOnError": { "description": "Will cause the module build to fail if there are any errors, to disable set to `false`.", "type": "boolean" diff --git a/test/fixtures/media/some-video.ts b/test/fixtures/media/some-video.ts new file mode 100644 index 0000000..d578c1f Binary files /dev/null and b/test/fixtures/media/some-video.ts differ diff --git a/test/fixtures/resource-query-entry.js b/test/fixtures/resource-query-entry.js new file mode 100644 index 0000000..d3683ff --- /dev/null +++ b/test/fixtures/resource-query-entry.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/no-unresolved +require('./media/some-video.ts?media'); diff --git a/test/resource-query.test.js b/test/resource-query.test.js new file mode 100644 index 0000000..38d098c --- /dev/null +++ b/test/resource-query.test.js @@ -0,0 +1,23 @@ +import pack from './utils/pack'; + +describe('resource-query', () => { + it('should exclude the match resource query', (done) => { + const compiler = pack( + 'resource-query', + { + resourceQueryExclude: /media/, + extensions: ['.js', '.ts'], + }, + { + module: { rules: [{ resourceQuery: /media/, type: 'asset/source' }] }, + } + ); + + compiler.run((err, stats) => { + expect(err).toBeNull(); + expect(stats.hasWarnings()).toBe(false); + expect(stats.hasErrors()).toBe(false); + done(); + }); + }); +}); diff --git a/test/utils/pack.js b/test/utils/pack.js index 328686c..37276fb 100644 --- a/test/utils/pack.js +++ b/test/utils/pack.js @@ -2,5 +2,12 @@ import webpack from 'webpack'; import conf from './conf'; +/** + * new a test webpack compiler + * @param {String} context + * @param {import('../../src/options').Options} pluginConf + * @param {webpack.Configuration} webpackConf + * @returns {ReturnType} + */ export default (context, pluginConf = {}, webpackConf = {}) => webpack(conf(context, pluginConf, webpackConf)); diff --git a/types/index.d.ts b/types/index.d.ts index 7a37c67..58cb948 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -8,13 +8,15 @@ declare class ESLintWebpackPlugin { options: import('./options').PluginOptions; /** * @param {Compiler} compiler - * @param {Options} options + * @param {Omit & {resourceQueryExclude: RegExp[]}} options * @param {string[]} wanted * @param {string[]} exclude */ run( compiler: Compiler, - options: Options, + options: Omit & { + resourceQueryExclude: RegExp[]; + }, wanted: string[], exclude: string[] ): Promise; diff --git a/types/options.d.ts b/types/options.d.ts index 7299069..e405d1a 100644 --- a/types/options.d.ts +++ b/types/options.d.ts @@ -25,6 +25,7 @@ export type PluginOptions = { quiet?: boolean | undefined; outputReport?: OutputReport | undefined; threads?: (number | boolean) | undefined; + resourceQueryExclude?: (RegExp | RegExp[]) | undefined; }; export type Options = PluginOptions & ESLintOptions; /** @typedef {import("eslint").ESLint.Options} ESLintOptions */ @@ -58,6 +59,7 @@ export type Options = PluginOptions & ESLintOptions; * @property {boolean=} quiet * @property {OutputReport=} outputReport * @property {number|boolean=} threads + * @property {RegExp|RegExp[]=} resourceQueryExclude */ /** @typedef {PluginOptions & ESLintOptions} Options */ /**