@hyeon/linter 11.0.1-dev.3.45 → 11.0.1-dev.3.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +154 -35
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -24,9 +24,9 @@ npm install --save-dev @hyeon/linter @biomejs/biome
24
24
  | **oxlint + oxfmt** | 139ms | **62x** 빠름 | **30x** 빠름 |
25
25
  | **Biome** | 377ms | **~20x** 빠름 | **10x** 빠름 |
26
26
 
27
- - oxlint이 Biome보다 ~2.5x 빠르지만, **둘 다 1초 미만**이라 개발자 피드백 루프에 체감 차이 없음
28
27
  - 셋 다 **Rust 기반 멀티스레드(rayon)** — 파일 수 증가 시 코어 수에 비례해 스케일
29
28
  - ESLint만 **싱글스레드(Node.js)** — 파일 수에 선형 비례해 느려짐
29
+ - oxlint이 Biome보다 ~2.5x 빠르지만, **둘 다 1초 미만**이라 체감 차이 없음
30
30
 
31
31
  ### 룰 커버리지
32
32
 
@@ -50,7 +50,157 @@ npm install --save-dev @hyeon/linter @biomejs/biome
50
50
  | side-effect import 처리 | 수동 | 무시 | ✅ auto chunk |
51
51
  | custom group (glob) | ❌ | 일부 | ✅ glob + `!` 예외 |
52
52
 
53
- **oxlint+oxfmt은 속도 최강이지만 import DX 격차가 일상 코딩에 매번 영향을 줌. Biome 기존 ESLint 경험의 대부분을 보존하면서 충분히 빠름.**
53
+ ### ESLint Biome 규칙 마이그레이션 커버리지
54
+
55
+ 기존 `@hyeon/linter` v10에서 사용하던 ESLint 규칙을 Biome에서 어떻게 커버하는지 전수 매핑입니다.
56
+
57
+ #### `@eslint/js` recommended (base.mjs)
58
+
59
+ > `@eslint/js` configs.recommended에 포함된 규칙들. Biome은 `"recommended": true`로 대부분 활성화됩니다.
60
+
61
+ | ESLint 규칙 | Biome 규칙 | 상태 |
62
+ |---|---|:---:|
63
+ | `constructor-super` | `noInvalidConstructorSuper` | ✅ |
64
+ | `for-direction` | `useValidForDirection` | ✅ |
65
+ | `getter-return` | `useGetterReturn` | ✅ |
66
+ | `no-async-promise-executor` | `noAsyncPromiseExecutor` | ✅ |
67
+ | `no-case-declarations` | `noSwitchDeclarations` | ✅ |
68
+ | `no-class-assign` | `noClassAssign` | ✅ |
69
+ | `no-compare-neg-zero` | `noCompareNegZero` | ✅ |
70
+ | `no-cond-assign` | `noAssignInExpressions` | ✅ |
71
+ | `no-const-assign` | `noConstAssign` | ✅ |
72
+ | `no-constant-condition` | `noConstantCondition` | ✅ |
73
+ | `no-control-regex` | `noControlCharactersInRegex` | ✅ |
74
+ | `no-debugger` | `noDebugger` | ✅ |
75
+ | `no-delete-var` | (TS 환경에서 불필요) | ➖ |
76
+ | `no-dupe-args` | `noDuplicateParameters` | ✅ |
77
+ | `no-dupe-class-members` | `noDuplicateClassMembers` | ✅ |
78
+ | `no-dupe-else-if` | `noDuplicateElseIf` | ✅ |
79
+ | `no-dupe-keys` | `noDuplicateObjectKeys` | ✅ |
80
+ | `no-duplicate-case` | `noDuplicateCase` | ✅ |
81
+ | `no-empty` | `noEmptyBlockStatements` | ✅ |
82
+ | `no-empty-character-class` | `noEmptyCharacterClassInRegex` | ✅ |
83
+ | `no-empty-pattern` | `noEmptyPattern` | ✅ |
84
+ | `no-ex-assign` | `noCatchAssign` | ✅ |
85
+ | `no-extra-boolean-cast` | `noExtraBooleanCast` | ✅ |
86
+ | `no-fallthrough` | `noFallthroughSwitchClause` | ✅ |
87
+ | `no-func-assign` | `noFunctionAssign` | ✅ |
88
+ | `no-global-assign` | `noGlobalAssign` | ✅ |
89
+ | `no-import-assign` | `noImportAssign` | ✅ |
90
+ | `no-inner-declarations` | `noInnerDeclarations` | ✅ |
91
+ | `no-irregular-whitespace` | `noIrregularWhitespace` | ✅ |
92
+ | `no-loss-of-precision` | `noPrecisionLoss` | ✅ |
93
+ | `no-misleading-character-class` | `noMisleadingCharacterClass` | ✅ |
94
+ | `no-new-native-nonconstructor` | `noInvalidBuiltinInstantiation` | ✅ |
95
+ | `no-nonoctal-decimal-escape` | `noNonoctalDecimalEscape` | ✅ |
96
+ | `no-obj-calls` | `noGlobalObjectCalls` | ✅ |
97
+ | `no-prototype-builtins` | `noPrototypeBuiltins` | ✅ |
98
+ | `no-redeclare` | `noRedeclare` | ✅ |
99
+ | `no-regex-spaces` | `noMultipleSpacesInRegex` | ✅ |
100
+ | `no-self-assign` | `noSelfAssign` | ✅ |
101
+ | `no-setter-return` | `noSetterReturn` | ✅ |
102
+ | `no-shadow-restricted-names` | `noShadowRestrictedNames` | ✅ |
103
+ | `no-sparse-arrays` | `noSparseArray` | ✅ |
104
+ | `no-this-before-super` | `noUnreachableSuper` | ✅ |
105
+ | `no-undef` | `noUndeclaredVariables` | ✅ |
106
+ | `no-unreachable` | `noUnreachable` | ✅ |
107
+ | `no-unsafe-finally` | `noUnsafeFinally` | ✅ |
108
+ | `no-unsafe-negation` | `noUnsafeNegation` | ✅ |
109
+ | `no-unsafe-optional-chaining` | `noUnsafeOptionalChaining` | ✅ |
110
+ | `no-unused-labels` | `noUnusedLabels` | ✅ |
111
+ | `no-unused-private-class-members` | `noUnusedPrivateClassMembers` | ✅ |
112
+ | `no-unused-vars` | `noUnusedVariables` | ✅ |
113
+ | `no-useless-catch` | `noUselessCatch` | ✅ |
114
+ | `no-useless-escape` | `noUselessEscapeInRegex` | ✅ |
115
+ | `no-with` | `noWith` | ✅ |
116
+ | `require-yield` | `useYield` | ✅ |
117
+ | `use-isnan` | `useIsNan` | ✅ |
118
+ | `valid-typeof` | `useValidTypeof` | ✅ |
119
+
120
+ #### `typescript-eslint` recommended (typescript.mjs)
121
+
122
+ | ESLint 규칙 | Biome 규칙 | 상태 | 비고 |
123
+ |---|---|:---:|---|
124
+ | `@ts/no-explicit-any` | `noExplicitAny` | ✅ | off으로 설정 |
125
+ | `@ts/no-unused-vars` | `noUnusedVariables` + `noUnusedFunctionParameters` | ✅ | `_` 접두사 패턴 지원 |
126
+ | `@ts/consistent-type-imports` | `useImportType` | ✅ | `inlineType` 스타일 지원 |
127
+ | `@ts/explicit-function-return-type` | `useExplicitType` | ✅ | off으로 설정 |
128
+ | `@ts/explicit-module-boundary-types` | `useExplicitType` | ✅ | off으로 설정 |
129
+ | `@ts/no-non-null-assertion` | `noNonNullAssertion` | ✅ | off으로 설정 |
130
+ | `@ts/no-empty-interface` | `noEmptyInterface` | ✅ | |
131
+ | `@ts/no-empty-object-type` | `noBannedTypes` | ✅ | |
132
+ | `@ts/ban-types` | `noBannedTypes` | ✅ | |
133
+ | `@ts/no-inferrable-types` | `noInferrableTypes` | ✅ | |
134
+ | `@ts/no-namespace` | `noNamespace` | ✅ | |
135
+ | `@ts/no-unnecessary-type-constraint` | `noUselessTypeConstraint` | ✅ | |
136
+ | `@ts/prefer-as-const` | `useAsConstAssertion` | ✅ | |
137
+
138
+ #### `eslint-plugin-react` + `react-refresh` (react.mjs)
139
+
140
+ | ESLint 규칙 | Biome 규칙 | 상태 | 비고 |
141
+ |---|---|:---:|---|
142
+ | `react/jsx-key` | `useJsxKeyInIterable` | ✅ | |
143
+ | `react/jsx-no-comment-textnodes` | `noCommentText` | ✅ | |
144
+ | `react/jsx-no-duplicate-props` | `noDuplicateJsxProps` | ✅ | |
145
+ | `react/jsx-no-target-blank` | `noBlankTarget` | ✅ | |
146
+ | `react/jsx-no-useless-fragment` | `noUselessFragments` | ✅ | |
147
+ | `react/no-children-prop` | `noChildrenProp` | ✅ | |
148
+ | `react/no-danger-with-children` | `noDangerouslySetInnerHtmlWithChildren` | ✅ | |
149
+ | `react/void-dom-elements-no-children` | `noVoidElementsWithChildren` | ✅ | |
150
+ | `react-hooks/rules-of-hooks` | `useHookAtTopLevel` | ✅ | |
151
+ | `react-hooks/exhaustive-deps` | `useExhaustiveDependencies` | ✅ | |
152
+ | `react-refresh/only-export-components` | `useComponentExportOnlyModules` | ✅ | |
153
+ | `react/display-name` | — | ❌ | Biome 미구현 |
154
+ | `react/no-unescaped-entities` | — | ❌ | Biome 미구현 |
155
+
156
+ #### Prettier + 스타일 규칙 (prettier.mjs)
157
+
158
+ | ESLint 규칙 | Biome 처리 | 상태 | 비고 |
159
+ |---|---|:---:|---|
160
+ | `prettier/prettier` (포맷 전체) | Biome formatter | ✅ | 단일 도구로 통합 |
161
+ | ↳ `trailingComma: all` | `trailingCommas: "all"` | ✅ | |
162
+ | ↳ `singleQuote: true` | `quoteStyle: "single"` | ✅ | |
163
+ | ↳ `semi: false` | `semicolons: "asNeeded"` | ✅ | |
164
+ | ↳ `tabWidth: 2` | `indentWidth: 2` | ✅ | |
165
+ | ↳ `printWidth: 120` | `lineWidth: 120` | ✅ | |
166
+ | ↳ `arrowParens: always` | `arrowParentheses: "always"` | ✅ | |
167
+ | ↳ `jsxSingleQuote: false` | `jsxQuoteStyle: "double"` | ✅ | |
168
+ | ↳ `@trivago/sort-imports` | `organizeImports` | ✅ | 그룹/정렬/병합 모두 지원 |
169
+ | ↳ `prettier-plugin-tailwindcss` | `useSortedClasses` | ✅ | Biome 내장 |
170
+ | `arrow-body-style` | — | ❌ | Biome 미구현 |
171
+ | `prefer-arrow-callback` | `useArrowFunction` | ✅ | |
172
+ | `curly` | `useBlockStatements` | ✅ | |
173
+ | `lines-around-comment` | — | ❌ | formatter 영역 |
174
+ | `no-confusing-arrow` | — | ❌ | Biome 미구현 |
175
+ | `no-mixed-operators` | — | ❌ | Biome 미구현 |
176
+ | `no-tabs` | formatter `indentStyle: "space"` | ✅ | |
177
+ | `quotes` | formatter `quoteStyle: "single"` | ✅ | |
178
+
179
+ #### `eslint-plugin-import-x` + 커스텀 (hansanghyeon.mjs)
180
+
181
+ | ESLint 규칙 | Biome 처리 | 상태 | 비고 |
182
+ |---|---|:---:|---|
183
+ | `import-x/first` | `organizeImports` chunk | ✅ | |
184
+ | `import-x/newline-after-import` | `organizeImports` `:BLANK_LINE:` | ✅ | |
185
+ | `import-x/no-duplicates` | `organizeImports` 자동 merge | ✅ | |
186
+ | `import-x/no-unresolved` | — | ➖ | 원래 off |
187
+ | `no-empty-pattern` | `noEmptyPattern` | ✅ | off으로 설정 |
188
+ | `camelcase` | `useNamingConvention` | ✅ | off으로 설정 |
189
+ | `class-methods-use-this` | — | ❌ | Biome 미구현 |
190
+ | `no-multi-spaces` | formatter | ✅ | |
191
+
192
+ ### 마이그레이션 커버리지 요약
193
+
194
+ | 카테고리 | 전체 규칙 | ✅ 커버 | ❌ 미커버 | ➖ 해당없음 |
195
+ |---|---|---|---|---|
196
+ | `@eslint/js` recommended | 52 | **50** | 0 | 2 |
197
+ | `typescript-eslint` | 13 | **13** | 0 | 0 |
198
+ | `eslint-plugin-react` + hooks + refresh | 13 | **11** | 2 | 0 |
199
+ | Prettier + 스타일 | 18 | **14** | 4 | 0 |
200
+ | `import-x` + 커스텀 | 8 | **6** | 1 | 1 |
201
+ | **합계** | **104** | **94 (90%)** | **7 (7%)** | **3 (3%)** |
202
+
203
+ 미커버 7개: `react/display-name`, `react/no-unescaped-entities`, `arrow-body-style`, `lines-around-comment`, `no-confusing-arrow`, `no-mixed-operators`, `class-methods-use-this` — 대부분 스타일 취향 규칙이며 실질적 버그 감지에는 영향 없음.
54
204
 
55
205
  ### 요약 매트릭스
56
206
 
@@ -62,35 +212,10 @@ npm install --save-dev @hyeon/linter @biomejs/biome
62
212
 
63
213
  ## 사용 가이드
64
214
 
65
- ### 린트 + 포맷 (`biome.json`)
66
-
67
- ```jsonc
68
- {
69
- "$schema": "https://biomejs.dev/schemas/2.0.0/schema.json",
70
- "linter": {
71
- "enabled": true,
72
- "rules": { "recommended": true }
73
- },
74
- "formatter": {
75
- "enabled": true,
76
- "indentStyle": "space",
77
- "indentWidth": 2,
78
- "lineWidth": 120
79
- },
80
- "assist": {
81
- "actions": {
82
- "source": {
83
- "organizeImports": "on"
84
- }
85
- }
86
- }
87
- }
88
- ```
89
-
90
215
  ### 실행
91
216
 
92
217
  ```bash
93
- # 린트 + 포맷 + import 정리 한 번에
218
+ # lint + format + import 정리 한 번에
94
219
  npx @biomejs/biome check --write .
95
220
 
96
221
  # CI (검사만, 수정 없음)
@@ -101,16 +226,10 @@ npx @biomejs/biome ci .
101
226
 
102
227
  v11은 **Breaking Change**입니다. ESLint/Prettier를 Biome으로 완전 교체합니다.
103
228
 
104
- ### 제거된 항목
105
-
106
- - ESLint 설정 export (`./recommended`, `./typescript`, `./react`, `./prettier`, `./hansanghyeon`)
107
- - `eslint`, `prettier` peerDependencies
108
- - 모든 ESLint/Prettier 플러그인 의존성
109
-
110
229
  ### 마이그레이션 방법
111
230
 
112
231
  1. `eslint.config.mjs` 삭제
113
- 2. `biome.json` 생성 (위 예시 참고)
232
+ 2. `biome.jsonc` 생성 또는 `@hyeon/linter/biome-config` 상속
114
233
  3. `eslint`, `prettier` 및 관련 플러그인 devDependencies 제거
115
234
  4. `@biomejs/biome` 설치
116
235
  5. lint 스크립트를 `biome check` 또는 `biome ci` 로 변경
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyeon/linter",
3
- "version": "11.0.1-dev.3.45",
3
+ "version": "11.0.1-dev.3.46",
4
4
  "description": "Biome-based lint, format, and import organize configuration",
5
5
  "main": "./src/index.mjs",
6
6
  "type": "module",