// NestJS eslint config
// @ts-check
import eslint from '@eslint/js';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import globals from 'globals';
import tseslint from 'typescript-eslint';
export default tseslint.config(
{
ignores: ['eslint.config.mjs'],
},
eslint.configs.recommended,
...tseslint.configs.recommendedTypeChecked,
eslintPluginPrettierRecommended,
{
languageOptions: {
globals: {
...globals.node,
...globals.jest,
},
sourceType: 'commonjs',
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/no-unsafe-argument': 'warn',
"prettier/prettier": ["error", { endOfLine: "auto" }],
},
},
);
// Vite 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, globalIgnores } from 'eslint/config'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
기본 제공되는 NestJS의 Eslint config 파일은 정적 분석을 중시하여, 타입 안정성과 런타임 안정성을 챙겼습니다. 다만 tslint로 불러오는 config 매서드의 경우 Deprecated로 더이상 권장하지 않는 방식입니다. 또한 성능 이슈가 있는 eslint-plugin-prettier 를 사용하고 있습니다.
Vite에서 제공하는 Eslint config의 경우 타입 정보 해석 없이 문법 및 구조 수준의 안정성만 챙기는 등, 런타입 오류를 예방하는 수준은 아닙니다.
// root/eslint.config.mjs
// @ts-check
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import { defineConfig } from 'eslint/config';
import prettierConfig from 'eslint-config-prettier';
export default defineConfig(
// JS 기본 추천 규칙
eslint.configs.recommended,
// TS 추천 (타입 기반 버그 방지)
tseslint.configs.strictTypeChecked,
// TS 스타일 추천 (일관된 코드 스타일)
tseslint.configs.stylisticTypeChecked,
// Formatter는 prettier로 적용
prettierConfig,
{
files: ['**/*.ts', '**/*.tsx'],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
// 무시할 경로
ignores: ['dist/**', 'build/**', 'node_modules/**'],
},
// JS 파일은 타입체킹 규칙 비활성화
{ files: ['**/*.js'], extends: [tseslint.configs.disableTypeChecked] }
);
// fe/eslint.config.mjs
import base from '../eslint.config.mjs';
import { defineConfig } from 'eslint/config';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
export default defineConfig(...base, {
files: ['**/*.{ts,tsx,js,jsx}'],
extends: [
reactHooks.configs['recommended-latest'],
reactRefresh.configs.vite,
],
languageOptions: {
globals: { ...globals.browser },
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
});
// be/eslint.config.mjs
import base from '../eslint.config.mjs';
import { defineConfig } from 'eslint/config';
import globals from 'globals';
export default defineConfig(...base, {
files: ['**/*.{ts,js}'],
languageOptions: {
globals: { ...globals.node },
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/no-unsafe-argument': 'warn',
},
},
});
fe와 be에 개별적으로 더 엄격한 규칙을 적용할 수 있지만, 공통적으로 FE / BE가 동일한 코드 품질 기준을 공유할 수 있도록 설정했습니다. 모든 TS 코드에서 Promise 누락, unsafe 접근, nullable 오용과 같은 실수를 막을 수 있습니다. 또한, eslint-config-prettier의 prettierConfig를 적용해, 코드 스타일인 prettier의 전적인 책임으로 수정하여 성능 문제를 해소했습니다.
fe 및 be 각각에 개별적으로 적용해야 하는 설정값은 위 처럼 root의 eslint 설정을 추가해서 구성할 수 있습니다.