Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/eslint-config-airbnb-base/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const base = require('./flat');

module.exports = [
...base,
{ rules: { 'comma-dangle': 'off', 'max-len': 'off' } },
{
files: ['test/**'],
rules: {
'no-shadow': 'off',
'id-length': ['error', { min: 2, properties: 'never', exceptions: ['t'] }],
},
},
];
44 changes: 44 additions & 0 deletions packages/eslint-config-airbnb-base/flat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const globals = require('globals');
const importPlugin = require('eslint-plugin-import');

const bestPractices = require('./rules/best-practices');
const errors = require('./rules/errors');
const es6 = require('./rules/es6');
const imports = require('./rules/imports');
const node = require('./rules/node');
const strict = require('./rules/strict');
const style = require('./rules/style');
const variables = require('./rules/variables');

module.exports = [
{
languageOptions: {
ecmaVersion: 2018,
sourceType: 'module',
globals: {
...globals.es2015,
...globals.node,
},
parserOptions: {
ecmaFeatures: {
generators: false,
objectLiteralDuplicateProperties: false,
},
},
},
plugins: {
import: importPlugin,
},
settings: imports.settings,
rules: {
...bestPractices.rules,
...errors.rules,
...node.rules,
...style.rules,
...variables.rules,
...es6.rules,
...imports.rules,
...strict.rules,
},
},
];
10 changes: 6 additions & 4 deletions packages/eslint-config-airbnb-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"./rules/imports": "./rules/imports.js",
"./rules/strict": "./rules/strict.js",
"./rules/variables": "./rules/variables.js",
"./flat": "./flat.js",
"./package.json": "./package.json"
},
"scripts": {
Expand Down Expand Up @@ -72,21 +73,22 @@
"babel-preset-airbnb": "^4.5.0",
"babel-tape-runner": "^3.0.0",
"eclint": "^2.8.1",
"eslint": "^7.32.0 || ^8.2.0",
"eslint-find-rules": "^4.1.0",
"eslint": "^7.32.0 || ^8.2.0 || ^9.0.0",
"eslint-find-rules": "^5.0.0",
"eslint-plugin-import": "^2.30.0",
"in-publish": "^2.0.1",
"safe-publish-latest": "^2.0.0",
"tape": "^5.9.0"
},
"peerDependencies": {
"eslint": "^7.32.0 || ^8.2.0",
"eslint": "^7.32.0 || ^8.2.0 || ^9.0.0",
"eslint-plugin-import": "^2.30.0"
},
"engines": {
"node": "^10.12.0 || >=12.0.0"
},
"dependencies": {
"confusing-browser-globals": "^1.0.11"
"confusing-browser-globals": "^1.0.11",
"globals": "^15.14.0"
}
}
12 changes: 6 additions & 6 deletions packages/eslint-config-airbnb-base/whitespace-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const { isArray } = Array;
const { entries } = Object;
const { ESLint } = require('eslint');

const baseConfig = require('.');
const isFlat = ESLint.configType === 'flat';
const baseConfig = isFlat ? require('./flat') : require('.');
const whitespaceRules = require('./whitespaceRules');

const severities = ['off', 'warn', 'error'];
Expand All @@ -20,11 +21,10 @@ function getSeverity(ruleConfig) {
}

async function onlyErrorOnRules(rulesToError, config) {
const errorsOnly = { ...config };
const cli = new ESLint({
useEslintrc: false,
baseConfig: config
});
const errorsOnly = isFlat ? { rules: {} } : { ...config };
const cli = isFlat
? new ESLint({ overrideConfigFile: true, overrideConfig: config })
: new ESLint({ useEslintrc: false, baseConfig: config });
const baseRules = (await cli.calculateConfigForFile(require.resolve('./'))).rules;

entries(baseRules).forEach((rule) => {
Expand Down
17 changes: 16 additions & 1 deletion packages/eslint-config-airbnb-base/whitespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,27 @@ if (CLIEngine) {
} else {
const path = require('path');
const { execSync } = require('child_process');
const { ESLint } = require('eslint');

// NOTE: ESLint adds runtime statistics to the output (so it's no longer JSON) if TIMING is set
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'), {
const ruleOverrides = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'), {
env: {
...process.env,
TIMING: undefined,
}
})));

if (ESLint.configType === 'flat') {
// In flat mode, whitespace-async.js outputs only { rules: {} } since plugins
// are not JSON-serializable. Merge the rule overrides with the full flat config
// so consumers get a complete config with plugins, settings, and languageOptions.
const flatConfig = require('./flat');
const lastConfig = flatConfig[flatConfig.length - 1];
module.exports = [
...flatConfig.slice(0, -1),
{ ...lastConfig, rules: { ...lastConfig.rules, ...ruleOverrides.rules } },
];
} else {
module.exports = ruleOverrides;
}
}
13 changes: 13 additions & 0 deletions packages/eslint-config-airbnb/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const airbnb = require('./flat');

module.exports = [
...airbnb,
{ rules: { 'comma-dangle': 'off' } },
{
files: ['test/**'],
rules: {
'no-shadow': 'off',
'id-length': ['error', { min: 2, properties: 'never', exceptions: ['t'] }],
},
},
];
1 change: 1 addition & 0 deletions packages/eslint-config-airbnb/flat-base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('eslint-config-airbnb-base/flat');
20 changes: 20 additions & 0 deletions packages/eslint-config-airbnb/flat-hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const reactHooksPlugin = require('eslint-plugin-react-hooks');

const reactHooks = require('./rules/react-hooks');

module.exports = [
{
files: ['**/*.{js,jsx,mjs,cjs}'],
plugins: {
'react-hooks': reactHooksPlugin,
},
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
rules: reactHooks.rules,
},
];
30 changes: 30 additions & 0 deletions packages/eslint-config-airbnb/flat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const reactPlugin = require('eslint-plugin-react');
const jsxA11yPlugin = require('eslint-plugin-jsx-a11y');

const baseFlatConfig = require('eslint-config-airbnb-base/flat');

const react = require('./rules/react');
const reactA11y = require('./rules/react-a11y');

module.exports = [
...baseFlatConfig,
{
files: ['**/*.{js,jsx,mjs,cjs}'],
plugins: {
react: reactPlugin,
'jsx-a11y': jsxA11yPlugin,
},
languageOptions: {
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
settings: react.settings,
rules: {
...react.rules,
...reactA11y.rules,
},
},
];
9 changes: 6 additions & 3 deletions packages/eslint-config-airbnb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"./rules/react": "./rules/react.js",
"./rules/react-a11y": "./rules/react-a11y.js",
"./rules/react-hooks": "./rules/react-hooks.js",
"./flat": "./flat.js",
"./flat-base": "./flat-base.js",
"./flat-hooks": "./flat-hooks.js",
"./package.json": "./package.json"
},
"scripts": {
Expand Down Expand Up @@ -73,8 +76,8 @@
"babel-preset-airbnb": "^4.5.0",
"babel-tape-runner": "^3.0.0",
"eclint": "^2.8.1",
"eslint": "^7.32.0 || ^8.2.0",
"eslint-find-rules": "^4.1.0",
"eslint": "^7.32.0 || ^8.2.0 || ^9.0.0",
"eslint-find-rules": "^5.0.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-react": "^7.36.1",
Expand All @@ -85,7 +88,7 @@
"tape": "^5.9.0"
},
"peerDependencies": {
"eslint": "^7.32.0 || ^8.2.0",
"eslint": "^7.32.0 || ^8.2.0 || ^9.0.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-react": "^7.36.1",
Expand Down
31 changes: 24 additions & 7 deletions packages/eslint-config-airbnb/test/test-react-order.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import eslintrc from '..';
import reactRules from '../rules/react';
import reactA11yRules from '../rules/react-a11y';

const isFlat = ESLint.configType === 'flat';

const rules = {
// It is okay to import devDependencies in tests.
'import/no-extraneous-dependencies': [2, { devDependencies: true }],
Expand All @@ -12,17 +14,32 @@ const rules = {
// otherwise we need some junk in our fixture code
'react/no-unused-class-component-methods': 0,
};
const cli = new (CLIEngine || ESLint)({
useEslintrc: false,
baseConfig: eslintrc,
...(CLIEngine ? { rules } : { overrideConfig: { rules } }),
});

function createCli() {
if (isFlat) {
// eslint-disable-next-line global-require
const flatConfig = require('../flat');
return new ESLint({
overrideConfigFile: true,
overrideConfig: [...flatConfig, { rules }],
});
}
return new (CLIEngine || ESLint)({
useEslintrc: false,
baseConfig: eslintrc,
...(CLIEngine ? { rules } : { overrideConfig: { rules } }),
});
}
const cli = createCli();

async function lint(text) {
// @see https://eslint.org/docs/developer-guide/nodejs-api.html#executeonfiles
// @see https://eslint.org/docs/developer-guide/nodejs-api.html#executeontext
const linter = CLIEngine ? cli.executeOnText(text) : await cli.lintText(text);
return (CLIEngine ? linter.results : linter)[0];
if (CLIEngine) {
return cli.executeOnText(text).results[0];
}
const results = await cli.lintText(text, isFlat ? { filePath: 'test.jsx' } : undefined);
return results[0];
}

function wrapComponent(body) {
Expand Down
12 changes: 6 additions & 6 deletions packages/eslint-config-airbnb/whitespace-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ const { isArray } = Array;
const { entries } = Object;
const { ESLint } = require('eslint');

const baseConfig = require('.');
const isFlat = ESLint.configType === 'flat';
const baseConfig = isFlat ? require('./flat') : require('.');
const whitespaceRules = require('./whitespaceRules');

const severities = ['off', 'warn', 'error'];
Expand All @@ -20,11 +21,10 @@ function getSeverity(ruleConfig) {
}

async function onlyErrorOnRules(rulesToError, config) {
const errorsOnly = { ...config };
const cli = new ESLint({
useEslintrc: false,
baseConfig: config
});
const errorsOnly = isFlat ? { rules: {} } : { ...config };
const cli = isFlat
? new ESLint({ overrideConfigFile: true, overrideConfig: config })
: new ESLint({ useEslintrc: false, baseConfig: config });
const baseRules = (await cli.calculateConfigForFile(require.resolve('./'))).rules;

entries(baseRules).forEach((rule) => {
Expand Down
17 changes: 16 additions & 1 deletion packages/eslint-config-airbnb/whitespace.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,27 @@ if (CLIEngine) {
} else {
const path = require('path');
const { execSync } = require('child_process');
const { ESLint } = require('eslint');

// NOTE: ESLint adds runtime statistics to the output (so it's no longer JSON) if TIMING is set
module.exports = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'), {
const ruleOverrides = JSON.parse(String(execSync(path.join(__dirname, 'whitespace-async.js'), {
env: {
...process.env,
TIMING: undefined,
}
})));

if (ESLint.configType === 'flat') {
// In flat mode, whitespace-async.js outputs only { rules: {} } since plugins
// are not JSON-serializable. Merge the rule overrides with the full flat config
// so consumers get a complete config with plugins, settings, and languageOptions.
const flatConfig = require('./flat');
const lastConfig = flatConfig[flatConfig.length - 1];
module.exports = [
...flatConfig.slice(0, -1),
{ ...lastConfig, rules: { ...lastConfig.rules, ...ruleOverrides.rules } },
];
} else {
module.exports = ruleOverrides;
}
}
Loading