Nextjs를 활용한 블로그 형식의 포트폴리오 제작을 진행하며 개인적인 관점에서 느낀점, 기술 기록용으로 작성될 예정입니다:). 흥미 위주로 서술한 만큼 오류가 있을 수 있습니다. 가벼운 마음으로 읽고 지적 해 주실 부분이 있으시다면 언제나 환영입니다! :)
지난번 작업에 이어 eslint, prettier 설정을 진행해보겠습니다.
ESLint
는 ES 와 Lint를 합성어다.
ES는 Ecma Script를 의미하며, Ecma라는 기구에서 만든 Script, 즉, 표준 Javascript를 의미
Lint는 에러가 있는 코드에 표시를 달아놓는 것
즉 javascript 프로젝트 내에서 문법을 검사하고 에러를 표시해주는 기능이다.
에러라는것이 정말로 문법상의 에러는 뿐만 아니라 지정해놓은 문법에 맞지 않을경우까지 포함된다.
혼자 진행하는 프로젝트라면 크게 의미가 없을수도 있으나, 여러 작업자들과 협업을 한다면 공통된 코딩 스타일을 맞춰 갈 수 있어 가독성이나 해석적 측면에서 효율이 좋다.
출처 : https://velog.io/@jiwon/ESlint
코드 정리 규칙을 세부적으로 설정해놓으면,
정해놓은 규칙에 맞게 자동으로 정렬해서 가독성을 높이고
코드 스타일을 통일할 수 있는 플러그인입니다.
출처 : https://velog.io/@mayinjanuary/Next.js-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0-ESLint-Prettier-%EC%84%A4%EC%A0%95#2-prettier-%EB%9E%80
작성해놓고 보니 ESLint와 prettier가 다르다는것은 알겠지만 크게 뭐가 다른지 이해가 잘 안되는 부분이 있는 것 같아 아래와 같이 정리해 보자.
javascript 언어 자체가 다소 느슨한 방식이다.
a = 2;
console.log(a) // 2
var a = 3;
console.log(a) // 3
a를 변수에 선언하지 않았음에도 에러가 없이 그대로 콘솔로그에 찍히고 있으며, 이런경우 당장에 문제는 없지만 코드량이 많아 질수록 가독성과 문제가 생겼을 경우 찾기가 쉽지 않다. 이를 방지하기 위해 ESLint를 사용하는 이유다.
// ESLint 적용
a = 2; // 'a' is not defined.
console.log(a) // 'a' is not defined.
var b = 3; // 'b' is assigned a value but never used.
에러가 발생한다. a가 변수로 선언 되지 않았는데 a를 수정하고 a를 콘솔로그로 찍은것에 대한 에러와 b는 변수로 선언하였으나 사용되지 않았다는 경고를 알림.
데모를 진행하고 싶은경우 ESLint 데모를 방문해 테스트 해보세요.
prettier는 팀원간의 코딩 스타일을 맞추기 위해서 사용된다.
// a개발자가 작성한 코드
const test = () => {
alert('테스트를 진행 중입니다.')
}
// b개발자가 작성한 코드
const test2 = () => {
alert("두번째 테스트를 진행중입니다.");
};
작성 스타일이 다르다. a개발자는 탭사이즈가 4이고 코드 마지막에 세미콜론으로 종료를 알리지 않았고, 반대로 b의 개발자의 경우 탭사이즈가 2이고 코드 마지막에 세미콜론을 작성하여 종료를 알리고 있는 코딩스타일이다.
지금의 경우 간단히 작성해서 코드이해가 되지만 규모가 커지면 개발자에 따라 같은 코드라도 가독성에 의해 익숙하지 않은 코드가 될 수도 있다.
그래서 prettier는 정해진 코드 작성 스타일을 잡아 두고 검사시에 가이드에 맞지 않을 경우 전체 코드를 새로 작성해주는 포맷터 기능
에 특화 되어있다.
// 탭사이즈는 2, 코드 종료시 세미콜론 작성으로 설정
// a개발자가 작성한 코드
const test = () => {
alert('테스트를 진행 중입니다.')
}
// prettier 검사 후
const test = () => {
alert('테스트를 진행 중입니다.');
};
즉 ESLint와 Prettier의 차이점은 기능적 측면으로 봤을때 ESLint안에 Prettier가 속한다 라고 볼 수 있다. 다만 둘을 같이 쓰는 경우 Prettier가 포맷터 기능에 더욱 특화 되어있기 때문에 ESLint의 포맷터 기능을 off하고 Prettier가 포맷터 기능을 대체 하는것이다.
ESLint설정의 경우 회사 혹은 팀그룹 간에 정해놓거나, 정해지지 않은 경우 기본 설정이 제공된다. 혹은 타 팀에서 설정을 제공하는 경우도 있다.
지금 포트폴리오는 기본적으로 설정된 문법 옵션도 충분하겠지만(혼자 작업하므로...) 연습을 위해 다소 까다로운 규칙을 설정해 보자.(헬게이트 오픈?)
현재 기준 가장 많이 사용되는건 Airbnb 에서 정의한 자바스크립트 규칙이다.
그래서 나도 Airbnb코드스타일을 적용해보기로 했다.
Airbnb Style Guide
Airbnb ESLint 가이드를 설치하려면 사전에 설치해야 하는 다른 패키지들이 있다.
다음 명령어를 통해 어떤 패키지들이 있는지 알아보자
※ ESLint와 Prettier는 개발단에서만 필요하므로 지난시간에 작성했던 devDependencies에 설정한다.
$ npm info "eslint-config-airbnb@latest" peerDependencies
$ npm i eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks -D
# 혹은
$ npm i --save-dev eslint eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks
eslint-plugin-import : ES6 의 import/export syntax 체크해주는 플러그인
eslint-plugin-jsx-a11y : 리액트 element 의 접근성 이슈를 체크해주는 플러그인
eslint-plugin-react : 리액트 규칙들을 추가해주는 플러그인
eslint-plugin-import : 리액트 hooks 규칙들을 플러그인
$ npm i prettier eslint-config-prettier eslint-plugin-prettier -D
# 혹은
$ npm i --save-dev eslint-config-prettier eslint-plugin-prettier
eslint-config-prettier : ESLint의 formatting 관련 설정 중 Prettier와 충돌하는 부분을 비활성화.
Prettier 에서 문법 관련된 ESlint 규칙을 사용하지 않게 되기 때문에 ESLint 는 자바스크립트 문법을 담당하고, 코드 스타일 정리는 Prettier 가 담당.
eslint-plugin-prettier : 원하는 형식의 formatting 을 설정.
ESLint 설정하는 방식은 여러가지가 있다.
일단 알고있는 방식과 구글링해서 다른 방식으로 설정하는 법 모두 작성해겠다.
$ npm i -g eslint
접미어 -g의 의미는 프로젝트에 설치하는것이 아닌 시스템에 설치하는것이다.
그래서 package.json에 작성되지 않고, 로컬에 설치된다.
windows 기준
설치 후에 다음명령어를 실행한다.
$ eslint --init
init 실행을 하게 되면 몇가지 질문을 던진 후 자동으로 .eslintrc.json
파일을 생성해 준다.
How would you like to use ESLint?
- To check syntax only // 구문만 확인
- To check syntax and find problems // 구문을 확인하고 문제를 찾음
- To check syntax, find problems, and enforce code style // 구문을 확인하고 문제를 찾고 코드 스타일을 적용
ESLint를 어느 부분까지 사용하겠냐는 질문이다.
3번의 경우 코드스타일을 적용하는 포맷터는 Prettier를 사용 하기 때문에 구문과 문제만 확인 하는 것을 체크하자.
What type of modules does your project use?
- JavaScript modules (import/export)
- CommonJS (require/exports)
- None of these
프로젝트에서 어느 유형의 문법을 사용하는지에 대한 질문으로 javascript module을 사용
Which framework does your project use?
- React
- Vue.js
- None of these
어느 유형의 프레임워크를 사용하는지에 대한 질문으로 next는 react기반임으로 react를 선택
Does your project use TypeScript?
- No
- Yes
typescript 사용여부를 묻는 질문으로 typescript를 지난 시간에 적용 했으니 yes를 선택
Where does your code run?
- Browser
- Node
javascript코드가 어디서 실행되는지에 대한 것으로 Browser 선택
What format do you want your config file to be in?
- Javascript
- YAML
- JSON
코드 구성파일을 어느것으로 만드는것에 대한 질문으로 javascript 설정
Would you like to install them now?
지금 바로 설치하겠느냐는 질문으로 Y
Which package manager do you want to use?
- npm
- yarn
- pnpm
어느 매니징 툴을 사용하느냐는 질문으로 나는 npm을 사용하므로 npm선택
마지막 질문이 끝나면 설치 후 해당 선택 옵션에 따라 .eslintrc.js 파일을 생성 해 준다.
프로젝트 루트(최상위 루트로 package.json과 동일선상)에 .eslintrc.json파일을 생성
무엇을 작성할지는 아래에 설명하겠다.
package.json에 eslintConfig 옵션으로 직접 작성 할수있다.
//package.json
...
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
}
...
보통 cli를 활용하거나 아니면 직접 파일을 생성해서 작성한다. 위에 소개한바와 같이 package.json에 직접 작성도 가능은 하나 설정량이 많아지면 package.json파일이 복잡해지므로 추천하진 않는다.
env
env는 사전 정의된 전역 변수 사용을 정의
extends 과 plugins
extends는 추가한 플러그인에서 사용할 규칙을 설정하는 곳으로 plugins에만 플러그인을 추가한다 해서 규칙이 적용되지 않으며 extends에 등록 해주어만 규칙이 등록된다.
parser
ESLint가 구문 분석을 위한 파서를 등록
parserOptions
parserOptions은 ESLint 사용을 위해 지원하려는 Javascript 언어 옵션을 지정
settings
세부 설정 (규칙) 추가
cli를 사용했다면 위의 질문에 의해 자동으로 아래와 같이 설정되어 있을것이다.
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
}
}
위 설정에 airbnb규칙을 추가해보자.
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"airbnb",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"react",
"react-hooks",
"@typescript-eslint",
"prettier"
],
"rules": {
"react/react-in-jsx-scope": 0,
"react/prefer-stateless-function": 0,
"react/jsx-filename-extension": 0,
"react/jsx-one-expression-per-line": 0,
"no-nested-ternary": 0
}
}
extends와 plugins에 airbnb lint와 react-hooks를 등록해 주었고 세부 추가룰을 넣었다.
.eslintrc.js 파일이 아닌 .eslintrc.json파일로 설정 한다면 .eslintrc.json에 아래의 코드를 넣자
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"airbnb",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"react",
"react-hooks",
"@typescript-eslint",
"prettier"
],
"rules": {
"react/react-in-jsx-scope": 0,
"react/prefer-stateless-function": 0,
"react/jsx-filename-extension": 0,
"react/jsx-one-expression-per-line": 0,
"no-nested-ternary": 0
}
}
이후 작성글들은 cli를 통해 작성된 것이므로 cli를 기준으로 작성하겠다.
vscode의 eslint 확장플러그인을 설치 하자
eslint플러그인 설치 후 vscode를 재 실행하고 서버를 가동시켜보자
$ npm run dev
갑자기 에러가 쏟아진다
살려줘...
아마 airbnb 작성가이드에 위배 된듯 보인다.
위의 에러들은 prettier 설정 및 실행을 하며 잡아보겠다.
Prettier 또한 ESLint처럼 사용하는 방법이 여러가지다. ESLint와 마찬가지로 아는 방식과 검색을 통해 나온 방식 모두 작성해보겠다.
일단 Prettier를 devDependencies에 설치해주자.
npm i -D prettier
$ npx prettier ".eslintrc.js"
위 명령어를 실행하면 어떻게 코드를 바꿔야 하는지 결과물을 보여준다.
$ npx prettier --write ".eslintrc.js"
혹은 위 명령어를 실행하면 포맷팅 된 코드를 직접 파일에 작성해준다.
실제로 ESLint를 막 적용했을때 쏟아지던 .eslintrc.js에 에러들이 모두 사라진것이 보인다.
module.exports = {
singleQuote: true, // 문자열을 사용 할 때에는 " 를 사용
semi: true, // 코드 종료시 무조건 ;(세미콜론)
useTabs: true, // tab 대신에 스페이스를 사용
tabWidth : 2 // 들여쓰기 크기
trailingComma : "all", // 객체나 배열의 마지막 값에도 , 를 붙임
printWidth : 80 // 한 줄의 최대 칸수
}
{
"singleQuote": false,
"semi": true,
"useTabs": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80
}
// package.json
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
// 추가
"format": "prettier --check --ignore-path .gitignore .",
"format:fix": "prettier --write --ignore-path .gitignore ."
},
위에서 수정되었던 .eslintrc.js의 코드를 다시 오류 상태로 바꾸고 테스트를 진행해보자
$ npm run format
오류가 발생한 파일을 알려준다.
@ npm run format:fix
오류가 발생한 파일을 규칙에 맞게 고쳐준다.
테스트를 진행 하려던 찰나 아직도 index.tsx에 에러가 있음을 발견했다.
index.tsx에 선언한 Index함수의 구성요소가 함수선언이 아니라는것이다.
타입지정에서도 NextPage타입지정도 해주었는데 이게 무슨 에러일까? 검색해보았다.
ESLint와 React의 규칙사이에 발생한 에러이다. .eslintrc.js에 룰을 추가해주자.
// .eslintrc.js
module.exports = {
...생략,
rules : {
...생략,
"react/function-component-definition": [
2,
{
namedComponents: "arrow-function",
unnamedComponents: "arrow-function",
},
],
}
}
룰을 추가하여 규칙충돌을 제거하고 나니 에러가 사라졌다.
깔끔
eslint와 prettier는 이번에 공부하며 처음 셋팅해보았습니다. 처음에는 저런 규칙들을 언제 맞춰가며 개발하나 싶었는데 의외로 prettier의 포맷팅이 편하고 강력한 플러그인이라는 것에 좀 놀랐습니다. webpack의 경우 당장에 셋팅을 할게 있겠다 싶었는데 아직 실제로 무언가를 작업한게 없어 틈틈히 작업 중간중간에 커스텀을 진행하도록 하겠습니다. :)