Skip to content

Commit ffdc457

Browse files
committed
fix(eslint): force eslint configuration check to be synchronous, thanks to sync-rpc
1 parent 2e77db6 commit ffdc457

File tree

6 files changed

+71
-51
lines changed

6 files changed

+71
-51
lines changed

lib/loaders/eslint.js

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,12 @@
99

1010
'use strict';
1111

12+
const forceSync = require('sync-rpc');
13+
const hasEslintConfiguration = forceSync(require.resolve('../utils/has-eslint-configuration'));
1214
const WebpackConfig = require('../WebpackConfig'); //eslint-disable-line no-unused-vars
1315
const loaderFeatures = require('../features');
1416
const applyOptionsCallback = require('../utils/apply-options-callback');
1517

16-
function isMissingConfigError(e) {
17-
if (!e.message || !e.message.includes('No ESLint configuration found')) {
18-
return false;
19-
}
20-
21-
return true;
22-
}
23-
2418
module.exports = {
2519
/**
2620
* @param {WebpackConfig} webpackConfig
@@ -29,19 +23,11 @@ module.exports = {
2923
getOptions(webpackConfig) {
3024
loaderFeatures.ensurePackagesExistAndAreCorrectVersion('eslint');
3125

32-
const eslint = require('eslint'); // eslint-disable-line node/no-unpublished-require
33-
const engine = new eslint.CLIEngine({
34-
cwd: webpackConfig.runtimeConfig.context,
35-
});
36-
37-
try {
38-
engine.getConfigForFile('webpack.config.js');
39-
} catch (e) {
40-
if (isMissingConfigError(e)) {
41-
const chalk = require('chalk');
42-
const packageHelper = require('../package-helper');
26+
if (!hasEslintConfiguration(webpackConfig)) {
27+
const chalk = require('chalk');
28+
const packageHelper = require('../package-helper');
4329

44-
const message = `No ESLint configration has been found.
30+
const message = `No ESLint configuration has been found.
4531
4632
${chalk.bgGreen.black('', 'FIX', '')} Run command ${chalk.yellow('./node_modules/.bin/eslint --init')} or manually create a ${chalk.yellow('.eslintrc.js')} file at the root of your project.
4733
@@ -57,10 +43,7 @@ module.exports = {
5743
Install ${chalk.yellow('babel-eslint')} to prevent potential parsing issues: ${packageHelper.getInstallCommand([[{ name: 'babel-eslint' }]])}
5844
5945
`;
60-
throw new Error(message);
61-
}
62-
63-
throw e;
46+
throw new Error(message);
6447
}
6548

6649
const eslintLoaderOptions = {

lib/plugins/eslint.js

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,13 @@
99

1010
'use strict';
1111

12+
const forceSync = require('sync-rpc');
13+
const hasEslintConfiguration = forceSync(require.resolve('../utils/has-eslint-configuration'));
1214
const WebpackConfig = require('../WebpackConfig'); //eslint-disable-line no-unused-vars
1315
const EslintPlugin = require('eslint-webpack-plugin'); //eslint-disable-line node/no-unpublished-require
1416
const applyOptionsCallback = require('../utils/apply-options-callback');
1517
const pluginFeatures = require('../features');
1618

17-
function isMissingConfigError(e) {
18-
if (!e.message || !e.message.includes('No ESLint configuration found')) {
19-
return false;
20-
}
21-
22-
return true;
23-
}
24-
2519
/**
2620
* Support for ESLint.
2721
*
@@ -33,21 +27,11 @@ module.exports = function(plugins, webpackConfig) {
3327
if (webpackConfig.useEslintPlugin) {
3428
pluginFeatures.ensurePackagesExistAndAreCorrectVersion('eslint_plugin');
3529

36-
const { ESLint } = require('eslint'); // eslint-disable-line node/no-unpublished-require
37-
const eslint = new ESLint({
38-
cwd: webpackConfig.runtimeConfig.context,
39-
});
40-
41-
try {
42-
(async function() {
43-
await eslint.calculateConfigForFile('webpack.config.js');
44-
})();
45-
} catch (e) {
46-
if (isMissingConfigError(e)) {
47-
const chalk = require('chalk');
48-
const packageHelper = require('../package-helper');
30+
if (!hasEslintConfiguration(webpackConfig)) {
31+
const chalk = require('chalk');
32+
const packageHelper = require('../package-helper');
4933

50-
const message = `No ESLint configuration has been found.
34+
const message = `No ESLint configuration has been found.
5135
5236
${chalk.bgGreen.black('', 'FIX', '')} Run command ${chalk.yellow('./node_modules/.bin/eslint --init')} or manually create a ${chalk.yellow('.eslintrc.js')} file at the root of your project.
5337
@@ -63,10 +47,7 @@ module.exports = {
6347
Install ${chalk.yellow('babel-eslint')} to prevent potential parsing issues: ${packageHelper.getInstallCommand([[{ name: 'babel-eslint' }]])}
6448
6549
`;
66-
throw new Error(message);
67-
}
68-
69-
throw e;
50+
throw new Error(message);
7051
}
7152

7253
const eslintPluginOptions = {

lib/utils/has-eslint-configuration.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* This file is part of the Symfony Webpack Encore package.
3+
*
4+
* (c) Fabien Potencier <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
10+
'use strict';
11+
12+
13+
function isMissingConfigError(e) {
14+
if (!e.message || !e.message.includes('No ESLint configuration found')) {
15+
return false;
16+
}
17+
18+
return true;
19+
}
20+
21+
/**
22+
* @returns {Promise<boolean>}
23+
*/
24+
module.exports = async function() {
25+
/**
26+
* @param {WebpackConfig} webpackConfig
27+
* @returns {Promise<boolean>}
28+
*/
29+
return async function(webpackConfig) {
30+
const { ESLint } = require('eslint'); // eslint-disable-line node/no-unpublished-require
31+
const eslint = new ESLint({
32+
cwd: webpackConfig.runtimeConfig.context,
33+
});
34+
35+
try {
36+
await eslint.calculateConfigForFile('webpack.config.js');
37+
} catch (e) {
38+
return !isMissingConfigError(e);
39+
}
40+
41+
return true;
42+
};
43+
};

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"resolve-url-loader": "^3.1.2",
4646
"semver": "^7.3.2",
4747
"style-loader": "^2.0.0",
48+
"sync-rpc": "^1.3.6",
4849
"terser-webpack-plugin": "^5.1.1",
4950
"tmp": "^0.2.1",
5051
"webpack": "^5.35",

test/functional.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1962,7 +1962,7 @@ module.exports = {
19621962

19631963
expect(() => {
19641964
testSetup.runWebpack(config, (webpackAssert, stats) => {});
1965-
}).to.throw('No ESLint configration has been found.');
1965+
}).to.throw('No ESLint configuration has been found.');
19661966
});
19671967

19681968
it('When enabled and without any configuration, ESLint will throw an error and a nice message should be displayed (eslint-webpack-plugin)', (done) => {

yarn.lock

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3619,6 +3619,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1:
36193619
has "^1.0.3"
36203620
has-symbols "^1.0.1"
36213621

3622+
get-port@^3.1.0:
3623+
version "3.2.0"
3624+
resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc"
3625+
integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=
3626+
36223627
get-stream@^6.0.0:
36233628
version "6.0.1"
36243629
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
@@ -6801,6 +6806,13 @@ symbol-tree@^3.2.2:
68016806
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
68026807
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
68036808

6809+
sync-rpc@^1.3.6:
6810+
version "1.3.6"
6811+
resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7"
6812+
integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==
6813+
dependencies:
6814+
get-port "^3.1.0"
6815+
68046816
table@^6.0.9:
68056817
version "6.7.1"
68066818
resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"

0 commit comments

Comments
 (0)