Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Dependencies
node_modules/

# Environment variables
.env
.env.*
!.env.example

# Production builds
out/
build/
dist/

# Cache Report
.cache/
.vite/
.vite-cache/
coverage/
tsconfig.tsbuildinfo

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

# Lock files
pnpm-lock.yaml
yarn.lock
package-lock.json

# IDE
.idea/

# OS
.DS_Store
Thumbs.db
16 changes: 16 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"arrowParens": "always",
"bracketSpacing": true,
"semi": true,
"singleQuote": false,
"jsxSingleQuote": false,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"endOfLine": "lf",
"quoteProps": "as-needed",
"trailingComma": "es5",
"proseWrap": "preserve",
"singleAttributePerLine": false
}

107 changes: 92 additions & 15 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,100 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import { defineConfig } from "eslint/config";
import importPlugin from "eslint-plugin-import";
import typescriptParser from "@typescript-eslint/parser";
import eslintConfigPrettier from "eslint-config-prettier";

export default defineConfig([
globalIgnores(['dist']),
{ ignores: ["dist", "node_modules", "build", "*.config.js", "*.config.ts"] },

importPlugin.flatConfigs.recommended,
importPlugin.flatConfigs.typescript,
js.configs.recommended,
...tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,

{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
files: ["**/*.{ts,tsx}"],
settings: {
react: {
version: "detect",
},
"import/resolver": {
typescript: {
alwaysTryTypes: true,
project: "./tsconfig.app.json",
},
},
},
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
sourceType: "module",
parser: typescriptParser,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
rules: {
"no-var": "error", // var 금지
"no-console": ["warn", { allow: ["warn", "error"] }], // console.log 경고

"no-unused-vars": "off", // ts 룰로 대체함
"@typescript-eslint/no-unused-vars": [
// 사용하지 않는 변수 경고
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],

"@typescript-eslint/consistent-type-imports": [
// type import 사용 권장
"error",
{ prefer: "type-imports" },
],
"@typescript-eslint/no-explicit-any": "warn", // any 사용 경고
"@typescript-eslint/no-non-null-assertion": "warn", // non-null assertion 경고

"react-hooks/rules-of-hooks": "error", // Hooks 규칙 준수
"react-hooks/exhaustive-deps": "warn", // useEffect 의존성 배열 검사

// import 정렬 order 설정
"import/order": [
"warn",
{
groups: [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index",
"type",
Copy link
Collaborator

@u-zzn u-zzn Jan 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import/order에서 "type" 그룹을 별도로 두고 마지막에 배치한 구조는 타입 import와 런타임 import를 명확히 구분하려는 의도로 해석되는 것 같네용!!

다만 이 설정이 @typescript-eslint/consistent-type-imports와 함께 적용될 경우, type import가 항상 분리·이동되면서 import 관련 diff가 커질 수 있는 포인트가 될 수도 있다고 하네요 ㅠㅠ

수빈님이 위에서 리뷰 달아주신 것과 같이 import 정렬 컨벤션을 한 번 확정하고 가면 좋을 것 같습니다!! :)

제가 리뷰달고 있는 이 경우는 제가 생각했을 때는 아래 예시와 같이 타입 importimport type으로 항상 분리하고, import/order"type" 그룹은 항상 마지막으로 두는 방식으로 가면 어떨까요?? ☺️
이렇게 하면 타입/런타임 import의 역할이 명확해지고, consistent-type-importsimport/order가 만들어내는 결과가 항상 동일해져서 자동 정렬로 인한 불필요한 import diff를 줄일 수 있을 것 같습니다!!

import fs from "node:fs";

import React from "react";
import { useQuery } from "@tanstack/react-query";

import { Button } from "@/shared/ui/Button";

import type { User } from "@/entities/user/model";

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 이해하기로는 '코드 작성 시에 type import를 가장 마지막에 하는 컨벤션을 지키자~' 로 이해했는데 맞을까요~??(코드 수정 x)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 맞습니다!! :)
앞으로는 type import를 항상 마지막에 두는 컨벤션으로 맞춰가면 좋겠다는 제안이었습니다 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋습니다! 웹파트 노션 > 코드 컨벤션 페이지에 해당 룰 추가해두도록 하겠습니다 좋은 의견 감사합니다 ☺️

],
"newlines-between": "always",
alphabetize: { order: "asc", caseInsensitive: true },
},
],
Comment on lines +82 to +98
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import를 할 때마다 모듈 종류에 상관없이 순서가 뒤죽박죽돼서 import문의 가독성이 좋지 않았던 경우가 많은데
그룹 별로 import 순서를 강제해서 일관성을 유지할 수 있게 되어 좋은 것 같아요 ♪(´▽`)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오호 import 순서 강제하는 거 너무 좋네요 😍

"import/first": "error", // import문 최상단 위치
"import/no-duplicates": "error", // 중복 import 금지
"import/no-unresolved": "off", // TS resolver가 처리
"import/default": "off", // default export 불필요한 경고 제거
"import/prefer-default-export": "off", // named export 사용(최적화 관점)

// Prettier와 충돌 방지
"arrow-body-style": "off",
"prefer-arrow-callback": "off",
},
},
])
eslintConfigPrettier,
]);
7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"eslint-import-resolver-typescript": "^4.4.4",
"react": "^19.2.0",
"react-dom": "^19.2.0"
},
Expand All @@ -18,11 +19,17 @@
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@typescript-eslint/eslint-plugin": "^8.51.0",
"@typescript-eslint/parser": "^8.51.0",
"@vitejs/plugin-react-swc": "^4.2.2",
"eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"prettier": "3.7.4",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4"
Expand Down
Loading