From bc444ff181edf60c308a4b7c682a9a5261d8523f Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Fri, 3 May 2019 22:40:23 +0200 Subject: [PATCH 1/6] eslint/vue: tweak `WebpackConfig#enableEslintLoader()` --- lib/WebpackConfig.js | 27 ++++++++++++++++----------- test/WebpackConfig.js | 12 ++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/lib/WebpackConfig.js b/lib/WebpackConfig.js index 308a2217..013f13c0 100644 --- a/lib/WebpackConfig.js +++ b/lib/WebpackConfig.js @@ -133,6 +133,9 @@ class WebpackConfig { this.vueOptions = { useJsx: false, }; + this.eslintOptions = { + lintVue: false, + }; // Features/Loaders options callbacks this.postCssLoaderOptionsCallback = () => {}; @@ -686,31 +689,33 @@ class WebpackConfig { this.vueOptions = vueOptions; } - enableEslintLoader(eslintLoaderOptionsOrCallback = () => {}) { + enableEslintLoader(eslintLoaderOptionsOrCallback = () => {}, eslintOptions = {}) { this.useEslintLoader = true; if (typeof eslintLoaderOptionsOrCallback === 'function') { this.eslintLoaderOptionsCallback = eslintLoaderOptionsOrCallback; - return; - } - - if (typeof eslintLoaderOptionsOrCallback === 'string') { + } else if (typeof eslintLoaderOptionsOrCallback === 'string') { logger.deprecation('enableEslintLoader: Extending from a configuration is deprecated, please use a configuration file instead. See https://eslint.org/docs/user-guide/configuring for more information.'); this.eslintLoaderOptionsCallback = (options) => { options.extends = eslintLoaderOptionsOrCallback; }; - return; - } - - if (typeof eslintLoaderOptionsOrCallback === 'object') { + } else if (typeof eslintLoaderOptionsOrCallback === 'object') { this.eslintLoaderOptionsCallback = (options) => { Object.assign(options, eslintLoaderOptionsOrCallback); }; - return; + } else { + throw new Error('Argument 1 to enableEslintLoader() must be either a string, object or callback function.'); + } + + // Check allowed keys + for (const key of Object.keys(eslintOptions)) { + if (!(key in this.eslintOptions)) { + throw new Error(`"${key}" is not a valid key for enableEslintLoader(). Valid keys: ${Object.keys(this.eslintOptions).join(', ')}.`); + } } - throw new Error('Argument 1 to enableEslintLoader() must be either a string, object or callback function.'); + this.eslintOptions = eslintOptions; } enableBuildNotifications(enabled = true, notifierPluginOptionsCallback = () => {}) { diff --git a/test/WebpackConfig.js b/test/WebpackConfig.js index b2311fbb..45e903e5 100644 --- a/test/WebpackConfig.js +++ b/test/WebpackConfig.js @@ -1277,4 +1277,16 @@ describe('WebpackConfig object', () => { expect(() => config.enableIntegrityHashes(true, ['sha1', 'foo', 'sha256'])).to.throw('Invalid hash algorithm "foo"'); }); }); + + describe('enableEslintLoader', () => { + it('Should validate Encore-specific options', () => { + const config = createConfig(); + + expect(() => { + config.enableEslintLoader(() => {}, { + notExisting: false, + }); + }).to.throw('"notExisting" is not a valid key for enableEslintLoader(). Valid keys: lintVue.'); + }); + }); }); From aa782dfcb43324640eb85c0b6af9f6e5a70a2aa9 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Fri, 3 May 2019 22:41:34 +0200 Subject: [PATCH 2/6] eslint/vue: implement `getTest()` on ESlint loader helper --- lib/loaders/eslint.js | 14 ++++++++++++++ test/loaders/eslint.js | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/loaders/eslint.js b/lib/loaders/eslint.js index e96c7788..5eeab576 100644 --- a/lib/loaders/eslint.js +++ b/lib/loaders/eslint.js @@ -69,5 +69,19 @@ Install ${chalk.yellow('babel-eslint')} to prevent potential parsing issues: ${p }; return applyOptionsCallback(webpackConfig.eslintLoaderOptionsCallback, eslintLoaderOptions); + }, + + /** + * @param {WebpackConfig} webpackConfig + * @return {RegExp} to use for eslint-loader `test` rule + */ + getTest(webpackConfig) { + const extensions = ['jsx?']; + + if (webpackConfig.eslintOptions.lintVue) { + extensions.push('vue'); + } + + return new RegExp(`\\.(${extensions.join('|')})$`); } }; diff --git a/test/loaders/eslint.js b/test/loaders/eslint.js index 570c13a9..41eebb2b 100644 --- a/test/loaders/eslint.js +++ b/test/loaders/eslint.js @@ -74,4 +74,21 @@ describe('loaders/eslint', () => { const actualOptions = eslintLoader.getOptions(config); expect(actualOptions).to.deep.equals({ foo: true }); }); + + it('getTest() base behavior', () => { + const config = createConfig(); + + const actualTest = eslintLoader.getTest(config); + expect(actualTest.toString()).to.equals(/\.(jsx?)$/.toString()); + }); + + it('getTest() with Vue', () => { + const config = createConfig(); + config.enableEslintLoader(() => {}, { + lintVue: true, + }); + + const actualTest = eslintLoader.getTest(config); + expect(actualTest.toString()).to.equals(/\.(jsx?|vue)$/.toString()); + }); }); From eb85b247e5fd9f15641435150d15f0cd502ac03b Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Fri, 3 May 2019 22:46:04 +0200 Subject: [PATCH 3/6] eslint/vue: tweak config-generator --- lib/config-generator.js | 2 +- test/config-generator.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/config-generator.js b/lib/config-generator.js index 087080c8..939f1aba 100644 --- a/lib/config-generator.js +++ b/lib/config-generator.js @@ -393,7 +393,7 @@ class ConfigGenerator { if (this.webpackConfig.useEslintLoader) { rules.push(applyRuleConfigurationCallback('eslint', { - test: /\.jsx?$/, + test: eslintLoaderUtil.getTest(this.webpackConfig), loader: 'eslint-loader', exclude: /node_modules/, enforce: 'pre', diff --git a/test/config-generator.js b/test/config-generator.js index 2e5a80f8..51e602b4 100644 --- a/test/config-generator.js +++ b/test/config-generator.js @@ -416,6 +416,22 @@ describe('The config-generator function', () => { expect(JSON.stringify(actualConfig.module.rules)).to.contain('eslint-loader'); expect(JSON.stringify(actualConfig.module.rules)).to.contain('extends-name'); }); + + it('enableEslintLoader(() => {}, {lintVue: true})', () => { + const config = createConfig(); + config.addEntry('main', './main'); + config.publicPath = '/'; + config.outputPath = '/tmp'; + config.enableEslintLoader(() => {}, { + lintVue: true, + }); + + const actualConfig = configGenerator(config); + expect(JSON.stringify(actualConfig.module.rules)).to.contain('eslint-loader'); + + const eslintRule = findRule(/\.(jsx?|vue)$/, actualConfig.module.rules); + expect(eslintRule.test.toString()).to.equal(/\.(jsx?|vue)$/.toString()); + }); }); describe('addLoader() adds a custom loader', () => { From 12b3f779d6893154e1639ed727236537e38c2664 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Fri, 3 May 2019 23:00:56 +0200 Subject: [PATCH 4/6] eslint/vue: add 2nd parameter to Encore#enableEslintLoader --- index.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 3c7e7906..9de92e3e 100644 --- a/index.js +++ b/index.js @@ -1106,13 +1106,26 @@ class Encore { * options.extends = 'airbnb'; * options.emitWarning = false; * }); + * + * // configure Encore-specific options + * Encore.enableEslintLoader(() => {}, { + * // set optional Encore-specific options, for instance: + * + * // lint `.vue` files + * lintVue: true + * }); * ``` * + * Supported options: + * * {boolean} lintVue (default=false) + * Configure the loader to lint `.vue` files + * * @param {string|object|function} eslintLoaderOptionsOrCallback + * @param {object} encoreOptions * @returns {Encore} */ - enableEslintLoader(eslintLoaderOptionsOrCallback = () => {}) { - webpackConfig.enableEslintLoader(eslintLoaderOptionsOrCallback); + enableEslintLoader(eslintLoaderOptionsOrCallback = () => {}, encoreOptions = {}) { + webpackConfig.enableEslintLoader(eslintLoaderOptionsOrCallback, encoreOptions); return this; } From 2f1e85bf332d8b2c86d182b4078bd576cc607694 Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Fri, 18 Oct 2019 19:08:08 +0200 Subject: [PATCH 5/6] chore: add comment for making .vue files lint working --- index.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 9de92e3e..1491e7a2 100644 --- a/index.js +++ b/index.js @@ -1111,7 +1111,7 @@ class Encore { * Encore.enableEslintLoader(() => {}, { * // set optional Encore-specific options, for instance: * - * // lint `.vue` files + * // lint `.vue` files, see below for more informatin about linting Vue files * lintVue: true * }); * ``` @@ -1120,6 +1120,18 @@ class Encore { * * {boolean} lintVue (default=false) * Configure the loader to lint `.vue` files * + * // Linting Vue files + * Encore.enableEslintLoader((options) => { + * // Deleting the hard-coded `parser` option prevent the error "Use the latest vue-eslint-parser", see: + * // - https://eslint.vuejs.org/user-guide/#what-is-the-use-the-latest-vue-eslint-parser-error + * // - https://github.com/symfony/webpack-encore/pull/574 + * // Note that it will not be mandatory anymore is some times. + * delete options.parser; + * }, { + * lintVue: true + * }); + * ``` + * * @param {string|object|function} eslintLoaderOptionsOrCallback * @param {object} encoreOptions * @returns {Encore} From 13b0750b0a8cd9329b51ead262eae45ce511580b Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Fri, 20 Mar 2020 22:12:59 +0100 Subject: [PATCH 6/6] chore: remove comment for vue files linting since #687 has been merged --- index.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/index.js b/index.js index 1491e7a2..cb49894f 100644 --- a/index.js +++ b/index.js @@ -1111,7 +1111,7 @@ class Encore { * Encore.enableEslintLoader(() => {}, { * // set optional Encore-specific options, for instance: * - * // lint `.vue` files, see below for more informatin about linting Vue files + * // lint `.vue` files * lintVue: true * }); * ``` @@ -1119,17 +1119,6 @@ class Encore { * Supported options: * * {boolean} lintVue (default=false) * Configure the loader to lint `.vue` files - * - * // Linting Vue files - * Encore.enableEslintLoader((options) => { - * // Deleting the hard-coded `parser` option prevent the error "Use the latest vue-eslint-parser", see: - * // - https://eslint.vuejs.org/user-guide/#what-is-the-use-the-latest-vue-eslint-parser-error - * // - https://github.com/symfony/webpack-encore/pull/574 - * // Note that it will not be mandatory anymore is some times. - * delete options.parser; - * }, { - * lintVue: true - * }); * ``` * * @param {string|object|function} eslintLoaderOptionsOrCallback