이번엔 풀스텍 세팅은 끝냈으니, 기본적인 코드 관련 세팅을 추가하려고 한다
가장 전형적인게 ESLint,Prettier일텐데 너무 처음부터 강하게 세팅해도 문제지만 적당히 조절해서 사용하면 배포환경에서의 에러를 미리 방지해주는 장점이 있다고 생각한다.
ESLint - 코드 문제점 찾아내고 일관된 코딩 스타일 유지 돕는 정적 코드 분석 도구(코드 품질검사 및 버그 방지)
Prettier - 코드 포맷팅 자동화하는 도구(코드 디자이너)
이 두개로 로컬에서 코드 작성할때 도움을 받을 예정이고
git에선
husky - git훅 쉽게 설정하는 도구(커밋, 푸쉬 전에 코드 검사 자동화), 커밋 전 자동 코드 검사
lint-staged - 스테이징된 파일만 린트 검사(변경된 파일만 검사하니 시간 절약)
위에 것들은 사실 이미 사용해보고 만족감을 느껴서 또 사용하려는건데 docker는 개념도 모르고 처음 도입해볼 예정이다
docker - 애플리케이션 컨테이너화하여 환경의존성 문제 해결
나는 개인프로젝트라 아직까진 사용해야할 필요함을 모르긴하겠지만 추후 넣어보고싶은 기능이다
장점
pnpm add -D -w eslint prettier eslint-config-prettier eslint-plugin-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
eslint - 코드 문제 찾아주는 핵심 도구
prettier - 코드 형식 자동 정리 도구
eslint-config-prettier - ESLint와 Prettier 충돌 안되도록 하는 설정
eslint-plugin-prettier - Prettier를 ESLint 규칙으로 실행할 수 있는 플로그인
typescript-eslint/eslint-plugin - ts용 ESLint 규칙
typescript-eslint/parser - ts코드를 ESLint가 이해할 수 있게 해주는 파서
module.exports = {
root: true,
// 여러 환경에서 코드가 실행될 수 있음을 명시
env: {
browser: true,
node: true,
es6: true,
},
// 기본 규칙 세트를 확장
extends: [
"eslint:recommended", // ESLint 기본 권장 규칙
"plugin:@typescript-eslint/recommended", // TypeScript 권장 규칙
"prettier", // Prettier와 충돌하는 ESLint 규칙 비활성화
],
parser: "@typescript-eslint/parser", // TypeScript 파서 사용
plugins: ["@typescript-eslint", "prettier"], // 사용할 플러그인
rules: {
// Prettier 규칙을 ESLint 오류로 표시
"prettier/prettier": "error",
// 사용하지 않는 변수는 경고 (단, 언더스코어로 시작하는 변수는 무시)
"@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }],
// 일부 TypeScript 규칙은 너무 엄격할 수 있어 비활성화
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
},
// 검사하지 않을 파일/디렉토리
ignorePatterns: ["node_modules/", "dist/", ".next/", "build/"],
};
기본적으론 ESLint가 추천하는 권장사항을 넣고,
prettier와 충돌할법한 규칙은 비활성화
ts권장 규칙을 넣은게 가장 좋은 것 같다.
{
"semi": true, // 문장 끝에 세미콜론 사용
"singleQuote": true, // 문자열에 작은따옴표 사용
"tabWidth": 2, // 탭 너비는 2칸
"trailingComma": "es5", // ES5에서 유효한 후행 쉼표 사용 (객체, 배열 등)
"printWidth": 100, // 한 줄의 최대 길이
"arrowParens": "avoid" // 화살표 함수의 매개변수가 하나일 때 괄호 생략
}
prettier도 일단 기본 세팅
의존성 패키지 무시
node_modules
빌드 결과물 무시
.next dist build
패키지 락 파일 무시 (자동 생성되므로)
pnpm-lock.yaml
.prettierignore 파일도 생성해서 처리안할 파일을 지정해준다
pnpm add -D -w husky lint-staged
로 깃허스키와 린트스테이지드를 설치ㅐ줬는데
여기서 -w를 넣지 않으면
모노레포 구조여서 에러가 발생한다.
터보레포로 구성한 내 프로젝트 모노레포 구조에선
이런 구조여서
pnpm은 루트에 패키지 설치하는걸 의도적으로 방지하려고 한다.
그러나 지금 내가 설치하는 것들은 전체 프로젝트에 적용할 도구들이여서 루트에 설치하기 위해 -w 플래그를 사용하였디
pnpm pkg set scripts.prepare="husky install”
그리고 이 명령어를 사용하면 package.json의 scripts 섹션에 prepare 스크립트 추가해서 husky install 명령을 실행하도록 설정해주는데,
새로운 환경에서 깃 클론할때 자동으로 허스키 설치하도록 도와준다
근데 여기서 잠깐,
챗봇통해 설치하니 안먹히는 명령어들이 있어서
허스키와 린트스테이지드는 다시 설치
pnpm exec husky init
로 설치해주고
그러나 설치가 안되어서
pnpm add -D -w husky
를 통해 루트 디렉토리에 설치
이후엔
npx husky init
이걸로 실행하면 .husky 디렉토리 생성하고 기본 설정 세팅됨
pnpm add -D -w lint-staged
lint-staged까지 설치해주고
"lint-staged": {
".{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
".{json,md}": [
"prettier --write"
]
}
package.json에 커밋 시 ts파일엔 ESLINT와 Prettier 실행하고 json/md파일엔 prettier만 실행하도록 지정함
이후 .husky 폴더의 pre-commit 파일안에
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
git에 스테이징 된 파일들 중에 커밋 전 코드 자동으로 검사하고 수정해 수정된 파일만 검사해준다는 의미
그리고 커밋 내용을 중구난방으로 적지 않도록
커밋 메시지 컨밴션도 husky로 제어할 수 있는데,
일단 그것을 위해 commitlint 설치를 해준다
pnpm add -D -w @commitlint/cli @commitlint/config-conventional @commitlint/types
그리고 commitlint.config.ts 파일에서
import type { UserConfig } from '@commitlint/types';
const config: UserConfig = {
extends: ['@commitlint/config-conventional']
};
export default config;
해당 내용을 추가해준다
type/commitlint/config-conventional 을 포함한 config를 선언해줬는데,
지원하는 타입들은
이건 커밋할때 까먹지 않게 commit-convention.md로 저장했고
husky 폴더에 commit-msg 파일에
commitlint를 적용했는데
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit "$1"
커밋 내용이 타입을 제대로 따르지 않으면 거부되도록 조치한 내용임
아마 오류가 걱정되기는 하는데 일단 여기까지 내용을 애드커밋을 해보면??
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
일단 해당 라인들은 최신 버전에선 동작하지 않아서 제거해주었고,
prettierrc에 주석 제거해주었고,
아예 .prettierrc가 아닌 .prettierrc.js로 만들어서
module.exports = {
semi: true, // 문장 끝에 세미콜론 사용
singleQuote: true, // 문자열에 작은따옴표 사용
tabWidth: 2, // 탭 너비는 2칸
trailingComma: "es5", // ES5에서 유효한 후행 쉼표 사용
printWidth: 100, // 한 줄 최대 100자
arrowParens: "avoid" // 화살표 함수 매개변수 괄호 최소화
};
주석까지 포함시켜주었다.
일단 허스키가 버전이 많이 바뀌면서 기존 명령어라던지 필요없는 내용때문에 에러가 많이 발생하는데,
eslint도 설정 파일 형식이 변경되서 .eslintrc.js대신 .eslint.config.js를 사용해야했다
https://eslint.org/docs/latest/use/configure/migration-guide
여기서 Eslint 마이그레이션 가이드가 있어서 참고해서 바꿔보려고 하는데
pnpm dlx @eslint/migrate-config .eslintrc.json
일단 해당 명령어로
기존 .eslintrc.js 설정을 새로운 eslint.config.js형식으로 변환시켜준다
그 다음에 내용에 module을 빼고
// eslint.config.js
import js from '@eslint/js';
import globals from 'globals';
export default [
js.configs.recommended,
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
...globals.browser,
...globals.node,
},
parser: (await import('@typescript-eslint/parser')).default,
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
},
plugins: {
'@typescript-eslint': (await import('@typescript-eslint/eslint-plugin'))
.default,
prettier: (await import('eslint-plugin-prettier')).default,
},
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/no-unused-vars': [
'warn',
{ argsIgnorePattern: '^_' },
],
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
},
},
{
ignores: ['node_modules/', 'dist/', '.next/', 'build/'],
},
];
이렇게 넣으니까 lint 에러가 떠서 보니
eslint.config.js가 es모듈형식인 import/export 형식을 사용하는데 node.js에선 인식을 못해서 문제가 발생하였다
확장자를 .mjs로 변결할수도있었지만
package.json에 type에 module을 넣어줘서 해결하였고,
prettier도 module.exports를 쓰는 .prettierrc.js 파일과도 충돌이 일어났다
.cjs로 확장자를 바꾸거나 export default로 ES모듈 형식을 수정해서 조치를 취할 수 있었는데 모듈 형식을 바꿔서 해결하였다
마지막으로 commitlint에 대소문자 규칙이 있어서 첫 글자엔 대문자를 쓰지말라고해서 빼서 조치하였다
엄청 여러 에러를 조금씩 수정해가서 결과만 나타냈지만, 초반에 이렇게 빡세게 설정해놓으면 이후가 편하기에 초반에 조금 고생좀 했다 후후후