-
코딩 스타일 통일하기: 우아한 방식으로 시작하는 모노레포 구성하기(ESLint, Prettier 설정)React 2024. 7. 21. 19:10반응형
배경
최근 회사에서 신규 프로젝트를 시작하면서 React 레파지토리를 만들게 되었다. 하지만 내가 기존에 사용하던 ESLint 및 Prettier 규칙이 회사에서 사용하는 것과 달랐다. 같은 코드 스타일과 형식을 유지하기 위해 동일한 설정을 공유하고자 했지만, 기존 설정에는 주석이나 설명이 없어 왜 특정 규칙을 사용하고 있는지 이해하기 어려웠다. 무엇보다 이거 또 복붙해야하나(?) 평소에도 프론트엔드 개발자로 혼자 근무해서 극한의 효율을 갈구하고 있기에 관련 레퍼런스를 찾아보았다.
참고할 만한 자료를 찾던 중 우아한 기술블로그에서 바로 내 상황에 똑맞는 포스팅을 발견했다. 이 글에서는 기술블로그를 따라 공용 ESLint 및 Prettier 설정을 만들고 적용하는 과정을 공유하고자 한다.
우아한 기술블로그의 영향
나는 Airbnb의 eslint-config-airbnb 패키지를 사용하고있었는데, 포스팅 본문에 이런 글이있었다.
이 글을 본 순간.. 심장을 관통하는 기분이었다. ㅎ
Airbnb 컨피그의 대안으로 Microsoft에서 관리하는 @rushstack/eslint-config 패키지를 사용하여 ESLint, Prettier를 설정하는 방법이 상세하게 작성되어있었다.
🏗️ Structure
📁 Monorepo: pnpm workspace로 관리 📂 Packages: 📂 eslint-config 📁 (Main) @rushstack/eslint-config 📁 prettier-config 📂 example - Vite 기반 - React 사용
⚙️ ESLint 설정
1. packages/eslint-config/mixins/react.js
React 프로젝트를 위한 ESLint 설정 파일이다. React 관련 플러그인을 포함하고 있으며, 다양한 규칙이 존재한다.module.exports = { plugins: ["react", "react-refresh", "jsx-a11y"], extends: [ "plugin:react/recommended", "plugin:react-hooks/recommended", "plugin:react/jsx-runtime", "plugin:@tanstack/eslint-plugin-query/recommended", ], settings: { react: { version: "detect", }, }, overrides: [ { files: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"], extends: ["plugin:testing-library/react"], rules: { "react-refresh/only-export-components": "off", }, }, ], rules: { "react-refresh/only-export-components": [ "warn", { allowConstantExport: true }, ], "jsx-a11y/alt-text": [ "warn", { elements: ["img"], }, ], "jsx-a11y/aria-props": "warn", "jsx-a11y/aria-proptypes": "warn", "jsx-a11y/aria-unsupported-elements": "warn", "jsx-a11y/role-has-required-aria-props": "warn", "jsx-a11y/role-supports-aria-props": "warn", "react/no-unknown-property": "off", "react/prop-types": "off", }, };
2. packages/eslint-config/index.js
공통으로 사용할 ESLint 설정 파일이다. Rush Stack ESLint 설정을 기반으로 하며, 필요한 플러그인과 규칙을 정의되어있다.
module.exports = { plugins: ["no-relative-import-paths"], extends: [ "@rushstack/eslint-config/profile/web-app", ], rules: { "@typescript-eslint/explicit-function-return-type": "off", }, settings: {}, };
3. packages/eslint-config/package.json
ESLint 설정 패키지의 의존성과 메타 데이터관련 파일이다.
{ "name": "@org/eslint-config", "main": "index.js", "version": "1.0.0", "dependencies": { "@rushstack/eslint-config": "3.6.8", "@rushstack/eslint-patch": "1.10.1", "@tanstack/eslint-plugin-query": "4.38.0", "eslint-plugin-cypress": "2.15.1", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-no-relative-import-paths": "1.5.3", "eslint-plugin-react": "7.34.1", "eslint-plugin-react-hooks": "4.6.0", "eslint-plugin-react-refresh": "0.4.6", "eslint-plugin-storybook": "0.8.0", "eslint-plugin-testing-library": "6.2.0" }, "peerDependencies": { "eslint": ">= 8", "typescript": ">= 5" } }
4. packages/eslint-config/patch.js
Rush Stack의 ESLint 패치를 적용하기 위한 파일이다.
require("@rushstack/eslint-patch/modern-module-resolution");
⚙️ Prettier 설정
1. packages/prettier-config/index.js
공통으로 사용할 Prettier 설정 파일이다.
module.exports = { printWidth: 100, trailingComma: "all", tabWidth: 2, semi: true, singleQuote: true, bracketSpacing: true, arrowParens: "always", useTabs: false, };
2. packages/prettier-config/package.json
Prettier 설정 패키지의 의존성과 메타 데이터를 정의한 파일이다.
{ "name": "@org/prettier-config", "main": "index.js", "version": "1.0.0", "peerDependencies": { "prettier": ">= 3" } }
⚙️ 예제 프로젝트 설정
우아한 기술 블로그에서 example 폴더를 만들어 공용 설정을 사용하는 예제를 참고해서 설정했다.
1. example/.eslintrc.cjs
require("@org/eslint-config/patch"); module.exports = { env: { browser: true, es2020: true }, extends: [ "@org/eslint-config", "@org/eslint-config/mixins/react", ], settings: { react: { version: "18.2", }, }, parserOptions: { project: true, tsconfigRootDir: __dirname, }, };
2. example/package.json
{ "name": "example", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,css,html}\"" }, "dependencies": { "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { "@org/eslint-config": "workspace:*", "@org/prettier-config": "workspace:*", "@types/react": "18.2.74", "@types/react-dom": "18.2.24", "@vitejs/plugin-react-swc": "3.6.0", "eslint": "8.57.0", "typescript": "5.4.4", "vite": "5.2.8" }, "prettier": "@org/prettier-config" }
⚙️ 스크립트 실행
공용 설정을 적용한 예제 프로젝트에서 ESLint와 Prettier를 실행한다.
Linting
pnpm --filter example lint
Formatting
pnpm example prettier
결론
이 과정을 통해 공용 ESLint 및 Prettier 설정을 만들고, 이를 신규 프로젝트에 적용함으로써 일관된 코드 스타일을 유지할 수 있게 되었다. 우아한 기술블로그에서 많은 영감을 받았으며, 주석을 통해 규칙의 목적을 명확히 하는 것이 특히 도움이 되었다. 앞으로도 이러한 설정을 통해 개발 생산성을 높이고, 팀 내 커뮤니케이션을 원활하게 할 수 있을 것으로 기대된다. (프론트엔드 개발자가 더 들어온다면..?)
📚 참고 사이트
반응형