Comment-as-command for one-off codemod with ESLint.
npm i eslint-plugin-command -D
In your flat config eslint.config.mjs
:
// eslint.config.mjs
import command from 'eslint-plugin-command/config'
export default [
// ... your other flat config
command(),
]
Convert an arrow function to a standard function declaration.
Trigger with /// to-function
comment (triple slashes) one line above the arrow function.
Triggers:
/// to-function
/// to-fn
/// 2f
/// to-function
const foo = async (msg: string): void => {
console.log(msg)
}
Will be converted to (the command comment will be removed along the way):
async function foo(msg: string): void {
console.log(msg)
}
Convert a standard function declaration to an arrow function.
Triggers:
/// to-arrow
/// 2a
/// to-arrow
function foo(msg: string): void {
console.log(msg)
}
Will be converted to:
const foo = (msg: string): void => {
console.log(msg)
}
Keep the object keys or array items sorted.
Triggers:
/// keep-sorted
// @keep-sorted
/// keep-sorted
const obj = {
b: 2,
a: 1,
c: 3,
}
Will be converted to:
/// keep-sorted
const obj = {
a: 1,
b: 2,
c: 3,
}
Different from the other commands, the comment will not be removed after transformation to keep the sorting.
Convert for-of/for-in loop to .forEach()
.
Triggers:
/// to-for-each
/// foreach
/// to-for-each
for (const item of items) {
if (!item)
continue
console.log(item)
}
Will be converted to:
items.forEach((item) => {
if (!item)
return
console.log(item)
})
For for-in loop:
/// to-for-each
for (const key in obj) {
if (!obj[key])
continue
console.log(obj[key])
}
Will be converted to:
Object.keys(obj).forEach((key) => {
if (!obj[key])
return
console.log(obj[key])
})
Convert .forEach()
to for-of loop.
Triggers:
/// to-for-of
/// forof
/// to-for-of
items.forEach((item) => {
if (!item)
return
console.log(item)
})
Will be converted to:
for (const item of items) {
if (!item)
continue
console.log(item)
}
Convert import statement to dynamic import.
Triggers:
/// to-dynamic-import
/// to-dynamic
/// to-dynamic-import
import bar, { foo } from './foo'
Will be converted to:
const { default: bar, foo } = await import('./foo')
It's also possible to define your custom commands.
// eslint.config.mjs
import command from 'eslint-plugin-command/config'
import { builtinCommands, defineCommand } from 'eslint-plugin-command/commands'
const myCommand = defineCommand({
name: 'my-command',
// RegExp to match the command comment (without leading `//`)
match: /^@my-command$/,
action(context) {
// Do something with the context
},
})
export default [
// ... your other flat config
command({
commands: [
...builtinCommands,
myCommand,
]
}),
]
You can refer to the built-in commands for examples.
MIT License © 2023-PRESENT Anthony Fu