πPutout plugin for eslint config
npm install @putout/plugin-eslint[NPMIMGURL]: https://img.shields.io/npm/v/@putout/plugin-eslint.svg?style=flat&longCache=true
[NPMURL]: https://npmjs.org/package/@putout/plugin-eslint"npm"
> Find and fix problems in your JavaScript code
>
> (c) eslint.org
πPutout plugin helps to automate fixing ESLint config.
```
npm i @putout/plugin-eslint -D
- β
add-putout;
- β
apply-define-config;
- β
apply-dir-to-flat;
- β
apply-ignores;
- β
apply-create-eslint;
- β
apply-match-to-flat;
- β
apply-safe-align;
- β
convert-export-match-to-declaration;
- β
convert-files-to-array;
- β
convert-ide-to-safe;
- β
convert-node-to-n;
- β
convert-plugins-array-to-object;
- β
convert-rc-to-flat;
- β
convert-require-to-import;
- β
declare;
- β
move-putout-to-end-of-extends;
- β
remove-no-missing;
- β
remove-useless-define-config;
- β
remove-no-unpublished-require;
- β
remove-no-unsupported-features;
- β
remove-overrides-with-empty-rules;
- β
remove-useless-slice;
- β
remove-useless-properties;
- β
remove-useless-match-to-flat;
- β
remove-parser-options;
- β
remove-suffix-config;
- β
remove-create-eslint-config-with-one-argument;
- β
remove-spread-from-create-eslint-config;
`json`
{
"rules": {
"eslint/add-putout": "on",
"eslint/apply-define-config": "on",
"eslint/apply-dir-to-flat": "on",
"eslint/apply-create-eslint": "on",
"eslint/apply-ignores": ["off", {
"ignores": ["**/fixture"]
}],
"eslint/apply-safe-align": "on",
"eslint/apply-match-to-flat": "on",
"eslint/declare": "on",
"eslint/move-putout-to-end-of-extends": "on",
"eslint/convert-export-match-to-decleration": "on",
"eslint/convert-files-to-array": "on",
"eslint/convert-ide-to-safe": "on",
"eslint/convert-require-to-import": "on",
"eslint/convert-node-to-n": "on",
"eslint/convert-plugins-array-to-object": "on",
"eslint/convert-rc-to-flat": "off",
"eslint/remove-no-missing": "on",
"eslint/remove-no-unpublished-require": "on",
"eslint/remove-no-unsupported-features": "on",
"eslint/remove-overrides-with-empty-rules": "on",
"eslint/remove-useless-slice": "on",
"eslint/remove-useless-define-config": "on",
"eslint/remove-useless-properties": "on",
"eslint/remove-useless-match-to-flat": "on",
"eslint/remove-parser-options": "on",
"eslint/remove-suffix-config": "on",
"eslint/remove-create-eslint-config-with-one-argument": "on",
"eslint/remove-spread-from-create-eslint-config": "on"
}
}
`diff`
{
"extends": [
+ "plugin:putout/safe+align",
"plugin:node/recommended"
],
"plugins": [
+ "putout",
"node"
]
}
Checkout in πPutout Editor.
`js
import {safeAlign} from 'eslint-plugin-putout';
import {createESLintConfig} from '@putout/eslint-flat';
export default createESLintConfig([
safeAlign, {
ignores: ['**/fixture'],
},
]);
`
`js
import {safeAlign} from 'eslint-plugin-putout';
import {defineConfig} from '@eslint/config';
export default defineConfig([
safeAlign, {
ignores: ['**/fixture'],
},
]);
`
Checkout in πPutout Editor.
Legacy config:
`diff`
{
"extends": [
"plugin:putout/safe+align",
"plugin:node/recommended"
],
"plugins": [
"putout",
"node"
],
"ignorePatterns": [
"**/fixture"
]
}
Flat config:
`diff`
-export default safeAlign;
+export default [
+ ...safeAlign, {
+ ignores: [
+ "**/fixture"
+ ]
+}];
Checkout in πPutout Editor.
`js`
export default [
...safeAlign, {
ignores: ['**/fixture'],
},
];
`js`
export default createESLintConfig([
safeAlign, {
ignores: ['**/fixture'],
},
]);
`diff`
{
- "rules": {
- "putout/align-spaces": "error"
- },
"extends": [
- "plugin:putout/safe",
+ "plugin:putout/safe+align",
"plugin:node/recommended"
],
"plugins": [
"putout",
"node"
]
}
matchToFlatDir() and mergeESLintConfigs supports __dirname or import.meta.url starting from v2 of @putout/eslint-flat.
Check out in πPutout Editor.
`js
const scriptsConfig = await matchToFlatDir('scripts');
const monoConfig = await mergeESLintConfigs(['codemods', 'packages', 'rules']);
module.exports = [
...scriptsConfig,
...monoConfig,
];
`
`js
// CommonJS
const scriptsConfig = await matchToFlatDir(__dirname, 'scripts');
// ESM
const monoConfig = await mergeESLintConfigs(import.meta.url, ['codemods', 'packages', 'rules']);
module.exports = [
...scriptsConfig,
...monoConfig,
];
`
Check out in πPutout Editor.
`js
import {safeAlign} from 'eslint-plugin-putout/config';
export default [
...safeAlign, {
files: ['*.d.ts'],
rules: {
'no-var': 'off',
},
}, {
files: ['.spec.'],
rules: {
'node/no-extraneous-import': 'off',
},
},
];
`
`js
import {safeAlign} from 'eslint-plugin-putout/config';
const config = matchToFlat({
'*.d.ts': {
'no-var': 'off',
},
'.spec.': {
'node/no-extraneous-import': 'off',
},
});
export default [
...safeAlign,
...config,
];
`
`json`
{
"extends": [
"plugin:putout/recommended",
"plugin:node/recommended"
],
"plugins": [
"putout",
"node"
]
}
`json`
{
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
}
`json`
{
"extends": [
"plugin:node/recommended",
"plugin:putout/ide"
],
"plugins": [
"putout",
"node"
]
}
`json`
{
"extends": [
"plugin:node/recommended",
"plugin:putout/safe"
],
"plugins": [
"putout",
"node"
]
}
Check it out in πPutout Editor.
`diff`
{
"overrides": [{
- "files": "test/*.js",
+ "files": ["test/*.js"],
"rules": {
"node/no-missing-require": "off"
}
}],
};
node/no-missing-require has no sense when type=module in package.json.
Check it out in πPutout Editor.
`diff`
{
"overrides": [{
"files": "test/*.js",
"rules": {
- "node/no-missing-require": "off"
+ "node/no-missing-import": "off"
}
}],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
node/remove-no-unpublished-require should be enabled, since this is a very useful rule, which shows what files should be add to .npmignore.
`diff`
{
"overrides": [{
"files": "test/*.js",
"rules": {
- "node/no-unpublished-require": "off"
}
}],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
node/remove-no-unsupported-features is already disabled in eslint-plugin-putout.
`diff`
{
"overrides": [{
"files": "test/*.js",
"rules": {
- "node/no-unpublished-require": "off"
}
}],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
overrides with rules: {} has no sense. Check out in πPutout Editor:
- remove empty rules;
- remove empty overrides;
Remove overrides with one element with empty rules:
`diff`
{
- "overrides": [{
- "files": "test/*.js",
- "rules": {
- }
- }],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
Or remove empty overrides:
`diff`
{
- "overrides": [],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
And ofcourse remove only elements with empty rules:
`diff`
{
"overrides": [{
- "files": "test/*.js",
- "rules": {
- }
- }, {
"files": "test/*.js",
"rules": {
"no-semi": "off"
}
}],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
> In flat config files, the globals, and parserOptions are consolidated under the languageOptions key;
>
> (c) eslint.org
Check out in πPutout Editor
`js`
const ruleTester = new RuleTester({
languageOptions: {
parserOptions: {
ecmaVersion: 2025,
sourceType: 'module',
},
},
});
`js`
const ruleTester = new RuleTester({
languageOptions: {
ecmaVersion: 2025,
sourceType: 'module',
},
});
Checkout in πPutout Editor.
`js`
import {safeAlign} from 'eslint-plugin-putout/config';
`js`
import {safeAlign} from 'eslint-plugin-putout';
Checkout in πPutout Editor.
`js`
export default createESLintConfig([safeAlign]);
`js`
export default safeAlign;
Checkout in πPutout Editor.
`js`
export default createESLintConfig([
safeAlign,
...matchToFlat(match),
]);
`js`
export default createESLintConfig([safeAlign, matchToFlat(match)]);
eslint-plugin-node is no longer supported. Better to use eslint-plugin-n.
`diff`
{
"extends": [
"plugin:putout/safe+align",
- "plugin:node/recommended"
+ "plugin:n/recommended"
],
"plugins": [
"putout",
- "node"
+ "n"
]
}
node/remove-no-missing-require and node/remove-no-missing-import doesn't supports exportseslint-plugin-putout
and already disabled by .
`diff`
{
"overrides": [{
"files": "test/*.js",
"rules": {
- "node/no-missing-require": "off",
- "node/no-missing-import": "off"
}
}],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};
Fixes code after convert-array-copy-to-slice.
Checkout in πPutout Editor.
`js
export default x.slice();
module.exports = x.slice();
`
`js
export default x;
module.exports = x;
`
Checkout in πPutout Editor.
`js`
export default defineConfig([safeAlign]);
`js`
export default safeAlign;
Checkout in πPutout Editor.
`js`
module.exports = [
...safeAlign, {
rules: {},
},
];
`js`
module.exports = safeAlign;
Checkout in πPutout Editor.
`js
import {safeAlign} from 'eslint-plugin-putout';
export let match;
export default createESLintConfig([safeAlign, matchToFlat(match)]);
`
`js
import {safeAlign} from 'eslint-plugin-putout';
export default safeAlign;
`
Fixes apply-match-to-flat.
Checkout in πPutout Editor.
`js
module.exports.match = {
'bin/**': {
'no-process-exit': 'off',
},
};
module.exports = [
...safeAlign, {
rules: {
'node/no-unsupported-features/node-builtins': 'off',
},
},
...matchToFlat(match),
];
`
`js
const match = {
'bin/**': {
'no-process-exit': 'off',
},
};
module.exports = [
...safeAlign, {
rules: {
'node/no-unsupported-features/node-builtins': 'off',
},
},
...matchToFlat(match),
];
module.exports.match = match;
`
Declare:
- safeAlign;
> On the surface, using a plugin in flat config looks very similar to using a plugin in eslintrc. The big difference is that eslintrc used strings whereas flat configs uses objects. Instead of specifying the name of a plugin, you import the plugin directly and place it into the plugins key.
>
> (c) eslint.org
Checkout in πPutout Editor.
`js
import {types} from 'putout';
const {react} = types;
export default {
plugins: [react],
};
module.exports = {
plugins: ['react'],
};
`
`js
import {types} from 'putout';
const {react} = types;
export default {
plugins: {
react,
},
};
module.exports = {
plugins: ['react'],
};
`
Checkout in πPutout Editor:
Converts .eslintrc.json:
`json`
{
"root": true,
"parser": "@typescript-eslint/parser",
"env": {
"node": true
},
"extends": ["eslint:recommended"],
"plugins": ["@nx"],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "error"
},
"overrides": [{
"files": ["*.json"],
"parser": "jsonc-eslint-parser"
}, {
"files": [
"*.ts",
"*.tsx",
"*.js",
"*.jsx"
],
"rules": {
"@nx/enforce-module-boundaries": ["error", {
"enforceBuildableLibDependency": true,
"allow": [],
"depConstraints": [{
"sourceTag": "*",
"onlyDependOnLibsWithTags": ["*"]
}]
}]
}
}]
}
To .eslint.config.js:
`js
const nxPlugin = require('@nx/eslint-plugin');
const js = require('@eslint/js');
const globals = require('globals');
const jsoncParser = require('jsonc-eslint-parser');
const tsParser = require('@typescript-eslint/parser');
module.exports = [
js.configs.recommended, {
plugins: {
'@nx': nxPlugin,
},
}, {
languageOptions: {
parser: tsParser,
globals: {
...globals.node,
},
},
rules: {
'@typescript-eslint/explicit-module-boundary-types': ['error'],
},
}, {
files: ['*.json'],
languageOptions: {
parser: jsoncParser,
},
rules: {},
}, {
files: [
'*.ts',
'*.tsx',
'*.js',
'*.jsx',
],
rules: {
'@nx/enforce-module-boundaries': ['error', {
enforceBuildableLibDependency: true,
allow: [],
depConstraints: [{
sourceTag: '*',
onlyDependOnLibsWithTags: ['*'],
}],
}],
},
}];
``
MIT