지속적인 통합은 개발자들이 변경 사항을 자주, 최소 하루에 한 번씩 코드 베이스에 병합하는 방법론입니다. 주요 목표는 코드를 자주 통합함으로써 통합 문제를 조기에 발견하고 해결하는 것입니다.
지속적인 배포는 변경 사항을 자동으로 프로덕션 환경에 배포하는 방법론입니다. 이는 지속적인 전달(Continuous Delivery)의 확장으로, 모든 코드 변경이 자동으로 릴리스 준비가 되며, 수동 개입 없이 프로덕션에 배포됩니다.
자동화된 배포: CI 파이프라인을 통과한 변경 사항이 자동으로 프로덕션 환경에 배포됩니다.
배포 파이프라인: 빌드, 테스트, 배포 과정을 정의한 파이프라인을 통해 변경 사항이 배포됩니다.
CI 과정에서 Lint와 Build를 설정했습니다. 버셀로 배포한 프로젝트여서 CI만 추가하였습니다.
빌드 또한 버셀이 진행하지만 CI에서 빌드하면 미리 오류를 잡을 수 있는 장점이 있습니다.
ESLint 설정은 아래에 따로 있습니다.
.github/workflows
폴더를 생성합니다. 이는 규칙으로 정해진 네이밍입니다.(파일명).yml
파일을 생성해 ci 로직을 작성합니다. .github/workflows/ci.yml
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Run ESLint
run: npm run lint
steps 하위의 name을 지정하지 않고도 간략하게 사용할 수 있습니다.
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v2
with:
node-version: '18'
- run: npm install
- run: npm run lint
코드를 설명하면 다음과 같습니다.
on: [pull_request]
: 모든 PR 이벤트가 발생할 때 이 워크플로우가 실행됩니다.
runs-on: ubuntu-latest
: Lint 작업을 실행할 환경을 지정합니다.
steps:
actions/checkout@v2
: 코드를 체크아웃합니다.
actions/setup-node@v2
: Node.js 환경을 설정합니다.
npm install
: 프로젝트 의존성을 설치합니다.
npm run lint
: ESLint를 실행합니다.
빌드도 추가한 최종 코드입니다.
name: CI
on: [pull_request]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v2
with:
node-version: '18'
- run: npm install
- run: npm run lint
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v2
with:
node-version: '18'
- run: npm install
- run: CI='false' npm run build
run: CI='false' npm run build
package.json 파일의 type이 module로 설정되어 있어, ESLint가 .eslintrc.js 파일을 ES Module로 인식하고 CommonJS로 처리하려 할 때 발생하는 문제입니다.
.eslintrc.js 파일을 .eslintrc.cjs
로 변경하여 해결
.eslintrc.cjs 파일만 만들면 ESLint가 제대로 동작하지 않습니다.
ESLint 규칙 알아보기 - eslint.org
npm install eslint --save-dev
이 명령어는 ESLint를 프로젝트의 개발 의존성에 추가하여 프로젝트에서 ESLint를 사용할 수 있게 됩니다.
이후에는 .eslintrc.cjs
파일 직접 작성하기 또는 npx eslint --init
명령어로 파일을 생성할 수 있습니다.
이 두가지의 차이점은 파일 형식과 구성 방식, 설정 내용입니다.
예시 코드:
// .eslintrc.js
module.exports = {
root: true,
env: { browser: true, es2021: true },
extends: [
'eslint:recommended', // 기본 ESLint 규칙
'plugin:react/recommended', // React 권장 규칙
'plugin:@typescript-eslint/recommended', // TypeScript 권장 규칙
'plugin:react-hooks/recommended', // React Hooks 권장 규칙
],
ignorePatterns: ['dist', '.eslintrc.js'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh', 'react'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'no-console': 'warn',
// console.log 사용 시 경고
},
}
npx eslint --init
:
ESLint 초기 설정을 도와줍니다. 실행하면 몇 가지 질문을 통해 프로젝트에 적합한 ESLint 설정 파일(.eslintrc)을 생성합니다.
초기 설정 단계를 거치면 eslint.config.js 파일이 생깁니다.
eslint와 prettier를 같이 사용할 때, 규칙이 다르다면 충돌이 발생할 수 있습니다.
npm install --save-dev eslint-config-prettier eslint-plugin-prettier
기존 설정에 eslint-config-prettier와 eslint-plugin-prettier를 추가합니다
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
},
extends: [
'eslint:recommended', // 기본 ESLint 규칙
'plugin:react/recommended', // React 권장 규칙
'plugin:@typescript-eslint/recommended', // TypeScript 권장 규칙
'plugin:react-hooks/recommended', // React Hooks 권장 규칙
'prettier', // Prettier와 충돌을 방지하기 위해 추가
'plugin:prettier/recommended', // Prettier 권장 규칙 및 eslint-plugin-prettier 활성화
],
ignorePatterns: ['dist', '.eslintrc.js'],
parser: '@typescript-eslint/parser',
plugins: [
'react-refresh',
'react',
'prettier' // Prettier 플러그인 추가
],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'no-console': 'warn', // console.log 사용 시 경고
'prettier/prettier': 'error', // Prettier 규칙을 ESLint 규칙으로 추가
},
};
eslint-config-prettier
는 Prettier와 충돌할 수 있는 ESLint 규칙을 비활성화합니다.eslint-plugin-prettier
는 Prettier의 규칙을 ESLint 규칙으로 적용해줍니다.plugin:prettier/recommended
설정은 Prettier 규칙을 기본 ESLint 규칙으로 추가하고, Prettier 플러그인을 활성화합니다.참고 - 협업을 위한 ESLint와 Prettier 환경설정하기
React
를 스코프에 포함하지 않은 오류'React' must be in scope when using JSX react/react-in-jsx-scope
'.eslintrc.cjs'
module.exports = {
// 다른 코드 생략
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'react/react-in-jsx-scope': 'off', // import React from 'react' 필요 없음
},
}
error 'className' is missing in props validation react/prop-types
6:24 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
22:52 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
/* eslint-disable @typescript-eslint/no-explicit-any */
function handleExternalLibrary(data: any) {
// ...
}
/* eslint-enable @typescript-eslint/no-explicit-any */
'특정 파일에서 규칙 비활성화하기'
/* eslint-disable @typescript-eslint/no-explicit-any */