diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 6de3be8..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - parser: '@typescript-eslint/parser', // 타입스크립트 파서 - extends: [ - 'eslint:recommended', // 기본 규칙 - 'plugin:react/recommended', // 리액트 규칙 - 'plugin:@typescript-eslint/recommended', // 타입스크립트 규칙 - 'prettier', // 프리티어와 충돌하는 룰을 비활성화 - ], - plugins: ['react', '@typescript-eslint'], // 플러그인 - rules: { - // 사용자 정의 규칙 - '@typescript-eslint/no-explicit-any': 'warn', // any 타입 검사 비활성화 - '@typescript-eslint/no-unused-vars': 'warn', // 사용하지 않는 변수 검사 비활성화 - }, - settings: { - react: { - version: 'detect', // 리액트 버전 자동 감지 - }, - }, -}; diff --git a/.github/workflows/action-check-pr.yaml b/.github/workflows/action-check-pr.yaml index c56d7e1..6690ab9 100644 --- a/.github/workflows/action-check-pr.yaml +++ b/.github/workflows/action-check-pr.yaml @@ -4,6 +4,10 @@ on: pull_request: types: [opened, edited, synchronize, reopened, ready_for_review] +permissions: + pull-requests: write # PR에 대한 쓰기 권한 부여 + issues: write # 이슈에 대한 쓰기 권한 부여 (라벨 추가를 위한) + jobs: check: runs-on: ubuntu-latest @@ -15,27 +19,29 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v2 with: - node-version: '18' # 사용하고자 하는 Node.js 버전 + node-version: '18' + - name: Install pnpm + run: npm install -g pnpm # pnpm을 전역으로 설치 - name: Install Dependencies - run: pnpm install # pnpm을 사용하여 의존성 설치 + run: pnpm install # pnpm을 사용하여 의존성 설치 - name: Run Lint - run: pnpm lint # 린트 실행 + run: pnpm lint # 린트 실행 - name: Run Prettier - run: pnpm format --check # 프리티어 체크 + run: pnpm format --check # 프리티어 체크 - - name: Build - run: pnpm build # 빌드 실행 + - name: Build # 머지하려는 브랜치가 main 브랜치이면 build:prod, dev 브랜치이면 build:dev + run: pnpm build:${{ github.event.pull_request.base.ref == 'main' && 'prod' || 'dev' }} label: runs-on: ubuntu-latest - needs: check # check 작업이 완료된 후 실행 + needs: check # check 작업이 완료된 후 실행 steps: - name: Add Labels - if: github.event.pull_request.draft == false # 드래프트가 아닐 경우에만 실행 - uses: actions/add-labels@v1 + if: github.event.pull_request.draft == false # 드래프트가 아닐 경우에만 실행 + uses: actions-ecosystem/action-add-labels@v1 # 라벨 추가 액션 with: - labels: ${{ github.event.pull_request.base.ref == 'dev' && 'dev' || github.event.pull_request.base.ref == 'main' && 'main'}} # dev로 머지 시 dev 라벨, main으로 머지 시 main 라벨 + labels: ${{ github.event.pull_request.base.ref == 'dev' && 'dev' || github.event.pull_request.base.ref == 'main' && 'main'}} # dev로 머지 시 dev 라벨, main으로 머지 시 main 라벨 diff --git a/.gitignore b/.gitignore index 39baa62..dd87e2d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ node_modules -.prettierrc +build diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..19a716b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "printWidth": 120 +} diff --git a/README.md b/README.md index 361bcfc..31571e3 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,21 @@ ## 컴포넌트 목록 ## 디렉토리 구조 + +```md +프로젝트 루트/ +├── node_modules/ +├── src/ # 소스 파일 디렉토리 +│ ├── components/ # React 컴포넌트 +│ ├── styles/ # 스타일 파일 (CSS, SCSS 등) +│ ├── utils/ # 유틸리티 함수 +│ ├── index.tsx # 애플리케이션 진입점 +│ └── App.tsx # 주요 React 컴포넌트 +├── .gitignore # Git 무시 파일 목록 +├── package.json # 프로젝트 메타데이터 및 의존성 +├── tsconfig.json # TypeScript 설정 파일 +├── webpack.config.js # Webpack 설정 파일 +├── .eslintrc.js # ESLint 설정 파일 +├── .prettierrc # Prettier 설정 파일 +└── README.md # 프로젝트 설명 문서 +``` diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..c1762c7 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,26 @@ +import { defineConfig } from 'eslint-define-config'; +import reactPlugin from 'eslint-plugin-react'; +import typescriptPlugin from '@typescript-eslint/eslint-plugin'; + +export default defineConfig([ + { + files: ['*.ts', '*.tsx'], // TypeScript 파일에 대한 설정 + languageOptions: { + parser: '@typescript-eslint/parser', // 타입스크립트 파서 + }, + plugins: { + react: reactPlugin, + '@typescript-eslint': typescriptPlugin, + }, + rules: { + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unused-vars': 'warn', + }, + settings: { + react: { + version: 'detect', + }, + }, + extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:@typescript-eslint/recommended', 'prettier'], + }, +]); diff --git a/package.json b/package.json index db3318a..e961426 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "format": "prettier --write .", - "lint": "eslint --fix .", + "lint": "eslint .", "dev": "cross-env NODE_ENV=development webpack serve --open", "build:dev": "cross-env NODE_ENV=development webpack", "build:prod": "cross-env NODE_ENV=production webpack", - "start:dev": "npm run build:dev && node dist/bundle.js", - "start:prod": "npm run build:prod && node dist/bundle.js" + "start:dev": "npm run build:dev && serve -s build", + "start:prod": "npm run build:prod && serve -s build" }, "keywords": [], "author": "", @@ -32,6 +32,7 @@ "@typescript-eslint/parser": "^8.13.0", "babel-loader": "^9.2.1", "eslint": "^9.14.0", + "eslint-define-config": "^2.1.0", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-hooks": "^5.0.0", "html-webpack-plugin": "^5.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9354d9f..2e9798b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ importers: eslint: specifier: ^9.14.0 version: 9.14.0 + eslint-define-config: + specifier: ^2.1.0 + version: 2.1.0 eslint-plugin-react: specifier: ^7.37.2 version: 7.37.2(eslint@9.14.0) @@ -1386,6 +1389,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + eslint-define-config@2.1.0: + resolution: {integrity: sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ==} + engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>=8.6.0'} + eslint-plugin-react-hooks@5.0.0: resolution: {integrity: sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==} engines: {node: '>=10'} @@ -4425,6 +4432,8 @@ snapshots: escape-string-regexp@4.0.0: {} + eslint-define-config@2.1.0: {} + eslint-plugin-react-hooks@5.0.0(eslint@9.14.0): dependencies: eslint: 9.14.0 diff --git a/index.html b/public/index.html similarity index 100% rename from index.html rename to public/index.html diff --git a/src/index.tsx b/src/index.tsx index fd9883d..3693e97 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,6 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import App from 'App'; +import App from '@/App'; const root = ReactDOM.createRoot(document.getElementById('root')!); root.render( diff --git a/webpack.config.js b/webpack.config.js index fa366c8..3f44d94 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,16 +7,19 @@ module.exports = { entry: './src/index.tsx', output: { filename: 'bundle.js', - path: path.resolve(__dirname, 'dist'), + path: path.resolve(__dirname, 'build'), clean: true, // 이전 빌드 파일 삭제 }, resolve: { + alias: { + '@': path.resolve(__dirname, 'src'), + }, extensions: ['.ts', '.tsx', '.js', '.jsx'], // 처리할 파일 확장자 }, module: { rules: [ { - test: /\.tsx?$/, // 타입스크립트 파일 처리 + test: /\.tsx?$/, // 타입스크립트 파일 처리 ts, tsx use: 'ts-loader', exclude: /node_modules/, }, @@ -25,7 +28,7 @@ module.exports = { mode: process.env.NODE_ENV || 'development', plugins: [ new HtmlWebpackPlugin({ - template: './index.html', // 기본 HTML 템플릿 + template: './public/index.html', // 기본 HTML 템플릿 }), ], devtool: process.env.NODE_ENV === 'development' ? 'source-map' : false, // 소스 맵