feat(eslint-plugin): new import dedupe rule
This commit is contained in:
parent
17670e8e38
commit
0ab9f88603
@ -186,10 +186,10 @@ module.exports = {
|
||||
'space-before-function-paren': [
|
||||
'error',
|
||||
{
|
||||
'anonymous': 'always',
|
||||
'named': 'never',
|
||||
'asyncArrow': 'always'
|
||||
}
|
||||
anonymous: 'always',
|
||||
named: 'never',
|
||||
asyncArrow: 'always',
|
||||
},
|
||||
],
|
||||
'no-multiple-empty-lines': ['error', { max: 1, maxBOF: 0, maxEOF: 1 }],
|
||||
|
||||
@ -300,8 +300,8 @@ module.exports = {
|
||||
'yml/no-empty-document': 'off',
|
||||
|
||||
// antfu
|
||||
// 'antfu/no-leading-newline': 'error',
|
||||
'antfu/if-newline': 'error',
|
||||
'antfu/import-dedupe': 'error',
|
||||
// 'antfu/prefer-inline-type-import': 'error',
|
||||
},
|
||||
}
|
||||
|
@ -2,8 +2,5 @@
|
||||
"extends": "@antfu",
|
||||
"plugins": [
|
||||
"antfu"
|
||||
],
|
||||
"rules": {
|
||||
"antfu/no-leading-newline": "error"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import ifNewline from './rules/if-newline'
|
||||
import noLeadingNewline from './rules/no-leading-newline'
|
||||
import importDedupe from './rules/import-dedupe'
|
||||
import preferInlineTypeImport from './rules/prefer-inline-type-import'
|
||||
|
||||
export default {
|
||||
rules: {
|
||||
'no-leading-newline': noLeadingNewline,
|
||||
'if-newline': ifNewline,
|
||||
'import-dedupe': importDedupe,
|
||||
'prefer-inline-type-import': preferInlineTypeImport,
|
||||
},
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { RuleTester } from '@typescript-eslint/utils/dist/ts-eslint'
|
||||
import { it } from 'vitest'
|
||||
import rule, { RULE_NAME } from './no-leading-newline'
|
||||
import rule, { RULE_NAME } from './import-dedupe'
|
||||
|
||||
const valids = [
|
||||
'import {} from \'foo\'',
|
||||
`// comment
|
||||
import {} from ''`,
|
||||
'import { a } from \'foo\'',
|
||||
]
|
||||
const invalids = [
|
||||
'\n\nimport {} from \'fo\'',
|
||||
[
|
||||
'import { a, b, a, a, c, a } from \'foo\'',
|
||||
'import { a, b, c, } from \'foo\'',
|
||||
],
|
||||
]
|
||||
|
||||
it('runs', () => {
|
||||
@ -19,9 +20,9 @@ it('runs', () => {
|
||||
ruleTester.run(RULE_NAME, rule, {
|
||||
valid: valids,
|
||||
invalid: invalids.map(i => ({
|
||||
code: i,
|
||||
output: i.trim(),
|
||||
errors: [{ messageId: 'noLeadingNewline' }],
|
||||
code: i[0],
|
||||
output: i[1],
|
||||
errors: [{ messageId: 'importDedupe' }, { messageId: 'importDedupe' }, { messageId: 'importDedupe' }],
|
||||
})),
|
||||
})
|
||||
})
|
55
packages/eslint-plugin-antfu/src/rules/import-dedupe.ts
Normal file
55
packages/eslint-plugin-antfu/src/rules/import-dedupe.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { createEslintRule } from '../utils'
|
||||
|
||||
export const RULE_NAME = 'import-dedupe'
|
||||
export type MessageIds = 'importDedupe'
|
||||
export type Options = []
|
||||
|
||||
export default createEslintRule<Options, MessageIds>({
|
||||
name: RULE_NAME,
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Fix duplication in imports',
|
||||
recommended: 'error',
|
||||
},
|
||||
fixable: 'code',
|
||||
schema: [],
|
||||
messages: {
|
||||
importDedupe: 'Expect no duplication in imports',
|
||||
},
|
||||
},
|
||||
defaultOptions: [],
|
||||
create: (context) => {
|
||||
return {
|
||||
ImportDeclaration(node) {
|
||||
if (node.specifiers.length <= 1)
|
||||
return
|
||||
|
||||
const names = new Set<string>()
|
||||
node.specifiers.forEach((n) => {
|
||||
const id = n.local.name
|
||||
if (names.has(id)) {
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: n.loc.end,
|
||||
end: n.loc.start,
|
||||
},
|
||||
messageId: 'importDedupe',
|
||||
fix(fixer) {
|
||||
const s = n.range[0]
|
||||
let e = n.range[1]
|
||||
if (context.getSourceCode().text[e] === ',')
|
||||
e += 1
|
||||
return fixer.removeRange([s, e])
|
||||
},
|
||||
})
|
||||
}
|
||||
names.add(id)
|
||||
})
|
||||
|
||||
// console.log(node)
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
@ -1,44 +0,0 @@
|
||||
import { createEslintRule } from '../utils'
|
||||
|
||||
export const RULE_NAME = 'no-leading-newline'
|
||||
export type MessageIds = 'noLeadingNewline'
|
||||
export type Options = []
|
||||
|
||||
export default createEslintRule<Options, MessageIds>({
|
||||
name: RULE_NAME,
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Do not allow leading newline',
|
||||
recommended: 'error',
|
||||
},
|
||||
fixable: 'whitespace',
|
||||
schema: [],
|
||||
messages: {
|
||||
noLeadingNewline: 'No leading newline allowed',
|
||||
},
|
||||
},
|
||||
defaultOptions: [],
|
||||
create: (context) => {
|
||||
return {
|
||||
Program(node) {
|
||||
const code = context.getSourceCode()
|
||||
const match = code.text.match(/^[\s]+/)?.[0] || ''
|
||||
if (match.includes('\n')) {
|
||||
const line = match.split('\n')
|
||||
context.report({
|
||||
node,
|
||||
loc: {
|
||||
start: { line: 0, column: 0 },
|
||||
end: { line: line.length - 1, column: line[line.length - 1].length },
|
||||
},
|
||||
messageId: 'noLeadingNewline',
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange([0, match.length], '')
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
Loading…
Reference in New Issue
Block a user