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.
This command takes an optional inline JSON configuration to specify the keys to sort.
/// keep-sorted { "keys": ["index", "name"] }
const arr = [
{ index: 4, name: 'foo' },
{ index: 2, name: 'bar' },
{ index: 2, name: 'apple' },
{ index: 0, name: 'zip' },
]
Will be converted to:
/// keep-sorted { "keys": ["index", "name"] }
const arr = [
{ index: 0, name: 'zip' },
{ index: 2, name: 'apple' },
{ index: 2, name: 'bar' },
{ index: 4, name: 'foo' },
]
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')
Convert template literals to string literals.
Triggers:
/// to-string-literal
/// to-sl
/// 2string-literal
/// 2sl
or if you fancy @
:
// @to-string-literal
// @to-sl
// @2string-literal
// @2sl
/// @2sl
const foo = `foo`
// @2sl
const quxx = `${qux}quxx`
// Also supports using numbers to specify which items need to be converted (starts from 1)
// @2sl 1 3
const bar = `bar`; const baz = `baz`; const qux = `qux`
Will be converted to:
const foo = 'bar'
// eslint-disable-next-line prefer-template
const quxx = qux + 'quxx'
const bar = 'bar'; const baz = `baz`; const qux = 'qux'
Convert string literals to template literals.
Triggers:
/// to-template-literal
/// to-tl
/// 2template-literal
/// 2tl
or if you fancy @
:
// @to-template-literal
// @to-tl
// @2template-literal
// @2tl
/// @2tl
const bar = 'bar'
// @2tl
// eslint-disable-next-line prefer-template
const quxx = qux + 'quxx'
// Also supports using numbers to specify which items need to be converted (starts from 1)
// @2tl 1 3
const foo = 'foo'; const baz = 'baz'; const qux = 'qux'
Will be converted to:
const bar = `bar`
const quxx = `${qux}quxx`
const foo = `foo`; const baz = 'baz'; const qux = `qux`
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