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;
{
"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"
}
}{
"extends": [
+ "plugin:putout/safe+align",
"plugin:node/recommended"
],
"plugins": [
+ "putout",
"node"
]
}Checkout in 🐊Putout Editor.
import {safeAlign} from 'eslint-plugin-putout';
import {createESLintConfig} from '@putout/eslint-flat';
export default createESLintConfig([
safeAlign, {
ignores: ['**/fixture'],
},
]);import {safeAlign} from 'eslint-plugin-putout';
import {defineConfig} from '@eslint/config';
export default defineConfig([
safeAlign, {
ignores: ['**/fixture'],
},
]);Checkout in 🐊Putout Editor. Legacy config:
{
"extends": [
"plugin:putout/safe+align",
"plugin:node/recommended"
],
"plugins": [
"putout",
"node"
],
"ignorePatterns": [
"**/fixture"
]
}Flat config:
-export default safeAlign;
+export default [
+ ...safeAlign, {
+ ignores: [
+ "**/fixture"
+ ]
+}];Checkout in 🐊Putout Editor.
export default [
...safeAlign, {
ignores: ['**/fixture'],
},
];export default createESLintConfig([
safeAlign, {
ignores: ['**/fixture'],
},
]);{
- "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.
const scriptsConfig = await matchToFlatDir('scripts');
const monoConfig = await mergeESLintConfigs(['codemods', 'packages', 'rules']);
module.exports = [
...scriptsConfig,
...monoConfig,
];// 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.
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',
},
},
];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,
];{
"extends": [
"plugin:putout/recommended",
"plugin:node/recommended"
],
"plugins": [
"putout",
"node"
]
}{
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
}{
"extends": [
"plugin:node/recommended",
"plugin:putout/ide"
],
"plugins": [
"putout",
"node"
]
}{
"extends": [
"plugin:node/recommended",
"plugin:putout/safe"
],
"plugins": [
"putout",
"node"
]
}Check it out in 🐊Putout Editor.
{
"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.
{
"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.
{
"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.
{
"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 overrides with one element with empty rules:
{
- "overrides": [{
- "files": "test/*.js",
- "rules": {
- }
- }],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};Or remove empty overrides:
{
- "overrides": [],
"extends": [
"plugin:node/recommended",
"plugin:putout/recommended"
],
"plugins": [
"putout",
"node"
]
};And ofcourse remove only elements with empty rules:
{
"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, andparserOptionsare consolidated under thelanguageOptionskey;(c) eslint.org
Check out in 🐊Putout Editor
const ruleTester = new RuleTester({
languageOptions: {
parserOptions: {
ecmaVersion: 2025,
sourceType: 'module',
},
},
});const ruleTester = new RuleTester({
languageOptions: {
ecmaVersion: 2025,
sourceType: 'module',
},
});Checkout in 🐊Putout Editor.
import {safeAlign} from 'eslint-plugin-putout/config';import {safeAlign} from 'eslint-plugin-putout';Checkout in 🐊Putout Editor.
export default createESLintConfig([safeAlign]);export default safeAlign;Checkout in 🐊Putout Editor.
export default createESLintConfig([
safeAlign,
...matchToFlat(match),
]);export default createESLintConfig([safeAlign, matchToFlat(match)]);eslint-plugin-node is no longer supported. Better to use eslint-plugin-n.
{
"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 exports
and already disabled by eslint-plugin-putout.
{
"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.
export default x.slice();
module.exports = x.slice();export default x;
module.exports = x;Checkout in 🐊Putout Editor.
export default defineConfig([safeAlign]);export default safeAlign;Checkout in 🐊Putout Editor.
module.exports = [
...safeAlign, {
rules: {},
},
];module.exports = safeAlign;Checkout in 🐊Putout Editor.
import {safeAlign} from 'eslint-plugin-putout';
export let match;
export default createESLintConfig([safeAlign, matchToFlat(match)]);import {safeAlign} from 'eslint-plugin-putout';
export default safeAlign;Fixes apply-match-to-flat. Checkout in 🐊Putout Editor.
module.exports.match = {
'bin/**': {
'no-process-exit': 'off',
},
};
module.exports = [
...safeAlign, {
rules: {
'node/no-unsupported-features/node-builtins': 'off',
},
},
...matchToFlat(match),
];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:
On the surface, using a plugin in
flat configlooks very similar to using a plugin ineslintrc. The big difference is thateslintrcusedstrings whereasflat configsusesobjects. Instead of specifying the name of a plugin, you import the plugin directly and place it into the pluginskey.(c) eslint.org
Checkout in 🐊Putout Editor.
import {types} from 'putout';
const {react} = types;
export default {
plugins: [react],
};
module.exports = {
plugins: ['react'],
};import {types} from 'putout';
const {react} = types;
export default {
plugins: {
react,
},
};
module.exports = {
plugins: ['react'],
};Checkout in 🐊Putout Editor:
Converts .eslintrc.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:
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