참고 블로그
김정환블로그 - 프론트엔드 개발환경의 이해: 린트
JBEE.io - Code Formatting 자동화
아래의 repository에서 모두 설치한 후의 설정파일들을 확인할 수 있습니다. commit history를 보며 하나씩 따라 해볼 수 있습니다.
bigsaigon333/javascript-package-initial-settings
우아한테크코스에서는 2주동안 미션을 페어와 진행합니다.
다르게 말하면, 2주가 지나면 새로운 미션을 새로운 페어와 시작해야 한다는 뜻입니다.
새로운 미션이 주어지면, 제일 처음하는 일은 repository를 로컬에 clone한 후, 이것 저것 환경설정을 하는 일입니다. 뭐든지 초반세팅을 잘해놔야 문제없이 할 수 있는 법이죠ㅎㅎ.
왜 이렇게 세팅을 하는지 한 줄 한 줄의 의미를 추가하여 여기에 기록해둡니다.
나중에 나를 위하여. 나중에 나와 함께할 페어를 위하여. 환경 설정으로 헤매는 누군가를 위하여.
package manager를 어떤 걸 쓸지 정합니다.
이제껏 npm 만 사용했었는데, 우테코에 들어오고 나서는 줄곧 yarn을 사용하고 있습니다.
npm과 yarn의 장단점은 무엇일까요?
npm의 경우 package 설치하는 도중에 코드의 실행을 허용합니다. 이러한 특징은 편리하나 안정성의 위험도를 증가시킵니다. 특히 정책 없이 등록하였던 패키지 제출물 부분에서 위험도가 높을 수 있습니다.
반면에 yarn은 yarn.lock이나 package.json으로 부터 설치만 합니다. 더 구체적으로 말하자면 yarn.lock은 모든 디바이스에 같은 패키지를 설치하는 것을 보장하여 다른 버전을 설치로 부터 버그가 오는 많은 양을 줄일 수 있다고 합니다.
아직 개발을 하면서 package manager의 차이를 느낄 정도에 이르지 못했습니다.
그저 npm에는 비교적 익숙하기 때문에 덜 익숙한 yarn을 익히기 위해 yarn을 사용하겠습니다.
참고 블로그
language.log - npm과 yarn
dongwon kim - Npm vs Yarn
yarn을 이용하여 package 초기화
$ yarn init
What is Prettier?
- An opinionated code formatter
- Supports many languages
- Integrates with most editors
- Has few options
Why?
- You press save and code is formatted
- No need to discuss style in code review
- Saves you time and energy
- And more
Prettier는 많은 언어를 지원하는 독선적인(opinionated) 코드 포매터입니다.
코드 포매터는 일관된 코드 스타일을 유지하기 위해 자동으로 코드를 정리해주는 도구를 의미합니다.
여기서 독선적인 이라는 단어가 매우 중요합니다. 코드 스타일에는 정답이 없습니다. 다수가 협업하는 환경에서는 모두가 공유하는 코드 스타일이 필요합니다. 각기 다른 스타일로 코드를 작성한다면, 유지보수에 매우 큰 힘이 들 것입니다. 여기서 문제는, 모두가 공유할 유일의 코드 스타일을 정하는 것이 쉽지 않다는 것입니다. 각기 다른 스타일로 여태까지 코드를 짠 사람들이 모인다면 당연히 이런 일이 생길 것입니다.
Prettier는 유저에게 코드 스타일을 지정할 수 없게 합니다. 매우 적은 옵션만을 제공하며, 그 외에는 Prettier가 정한 룰대로 코드를 정리해버립니다. Prettier의 철학은 코드 스타일을 정하는데에 힘을 빼지 말고, 우리가 정해주는 대로 따르라는 것입니다. 따라서 Prettier는 매우 독선적입니다.
Why Prettier?
또한, Prettier는 매우 적은 옵션만을 제공하지만, 이 또한 사용하지 않을 것을 권장하고 있습니다. 즉, 어떤 옵션을 선택할 것인지로 무의미한 논쟁을 하지 말라는 의미입니다. 이들이 제시하는 최선의 방안은 Prettier의 default를 그대로 따르라는 것입니다. 또한 prettier 설치시에 package.json에 정확한 버젼을 기입하여 모두가 동일한 prettier를 설치하게끔 하고 있습니다.
$ yarn add prettier --dev --exact
# 별도로 옵션을 설정하지 않고 기본 설정 그대로 사용
$ echo {} > .prettierrc.json
다만, IDE의 설정과 Prettier의 default옵션이 상충된다면 이는 개발시에 큰 혼란을 불어일으킬 수도 있습니다. IDE에서는 탭 하나에 스페이스 4개로 치환하여 사용하나, prettier는 탭 하나를 항상 스페이스 2개로 치환하니, 매번 작성후 prettier에 의해 수정이 반복되는 패턴일 것입니다. 따라서, 원칙적으로는 prettier의 default옵션을 사용하되, IDE와 관련된 사항들은 아래의 5. editorconfig 를 사용하여 적용할 생각입니다.
ESLint is a static code analysis tool for identifying problematic patterns found in JavaScript code. It was created by Nicholas C. Zakas in 2013. Rules in ESLint are configurable, and customized rules can be defined and loaded. ESLint covers both code quality and coding style issues.
wikipedia
esLint는 JS 코드에서 발견되는 문제가 있는 패턴을 식별하기 위한 정적 코드 분석 도구입니다.
JS는 동적 타입 언어로서 별도의 컴파일이 필요없는 인터프리터 언어입니다.
따라서 실제로 실행시키기 전까지는 어떤 에러가 있는지 알 수 없습니다.
이러한 단점을 보완하기 위하여 esLint는 코드를 실행시키기 전에 코드를 분석하여 문제가 될 만한 부분을 사전에 알려주는 역할을 합니다.
eslint를 통해 에러가 적은 코드를 더 빠르게 작성할 수 있습니다.
eslint는 제품의 릴리즈나 구동시 꼭 필요한 모듈이 아닌 개발시에만 필요로 하는 package이므로 devDependencies로 설치합니다.
$ yarn add eslint --dev
yarn eslint --init
커맨드를 통해 eslint 설정파일을 생성합니다. 저는 현재 브라우져에서 Vanilla JS로 개발하고 있으므로, 이에 맞게 설정합니다.
$ yarn eslint --init
yarn run v1.22.10
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JSON
Successfully created .eslintrc.json file
Done in 13.17s.
// .eslintrc.json
{
"env": {
"browser": true,
"es2021": true
},
"extends": ["airbnb-base", "prettier", "plugin:cypress/recommended"],
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"import/extensions": ["error", "always"]
},
"plugins": ["cypress"],
"ignorePatterns": [
"cypress/fixtures/*",
"cypress/plugins/*",
"cypress/support/*"
]
}
eslint에서는 어떤 코드를 문제로 볼지(rules)를 사용자가 지정할 수 있습니다. 이러한 rules를 하나하나 추가할 수도 있지만, 이미 유용한 rules를 모아둔 것을 가지고 올 수도 있습니다.
airbnb JS style은 해당 JS style에 대한 문서화가 잘 되어 있어 매우 유용하다는 느낌을 받았습니다. 이에 이번 프로젝트에서도 airbnb JS style을 적용하겠습니다. 이외에도 google JS style, eslint:recommended 등을 사용할 수 있습니다.
# yarn을 사용하고 있으면 자동으로 yarn을 사용하여 설치됩니다. 또한 eslint의 버젼도 바뀔수 있습니다.
$ npx install-peerdeps --dev eslint-config-airbnb-base
※ airbnb-base 에는 react와 관련된 rules가 포함되어 있지 않아, Vanilla JS로 개발시에 적합합니다.
eslint는 일부 코드 포맷팅 기능도 있습니다. 따라서 prettier가 강제로 적용한 코드 포맷에 대하여 eslint가 이를 문제시 삼는 경우가 있습니다. 이러한 경우를 위하여 eslint-config-prettier를 설정하면 eslint에 적용된 rules 중 코드 포맷팅 관련된 것을 모두 취소합니다. prettier에서 말하고 있는 eslint와의 조화로운 사용법은 코드 포맷팅은 prettier에게 맡기고, eslint는 코드 퀄리티와 관련된, 버그를 잡는데 쓰라는 것입니다.
use Prettier for formatting and linters for catching bugs!
$ yarn add eslint-config-prettier --dev
Cypress는 E2E 테스트를 위한 테스트 프레임워크입니다. cypress plugin을 설치하면 cypress commands에 대한 버그도 eslint에서 찾아줍니다.
$ yarn add cypress --dev
$ yarn add eslint-plugin-cypress --dev
다수의 개발자가 다양한 IDE로 개발을 할 경우 일관적인 코딩 스타일을 적용할 수 있기 위한 툴으로서 editorconfig 라는 프로젝트가 있습니다. .editorconfig 파일에 관련된 룰을 추가하면 IDE에 따라서 자동으로 또는 익스텐션 설치후에 적용됩니다.
vscode에서는 EditorConfig for VS Code 라는 익스텐션을 설치하면, .editorconfig 파일에 맞추어 user settings를 변경해줍니다.
EditorConfig
EditorConfig for VS Code
// .editorconfig
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
vscode로 개발을 하고 있으니, 코드에 영향을 줄 수 있는 항목에 대해서는 설정을 공유하는 것이 좋습니다.
// .vscode/settings.json
// ※ json파일에는 주석이 포함되면 안됩니다. 아래의 주석은 단순히 설명을 위하여 임의로 추가한 것입니다.
{
"files.autoSave": "onFocusChange", // Focus가 바뀔 때마다 파일을 저장한다
"files.trimTrailingWhitespace": true, // 파일을 저장할때 각 줄 끝의 불필요한 공백문자를 제거한다
// 이는 editorconfig에 따라 설정되는 부분이나,
// vscode 설정이 false인 경우 editorconfig에서 true로 하여도
// 적용되지 않는 이슈가 있어 추가
"editor.defaultFormatter": "esbenp.prettier-vscode", // prettier extension을 코드 포맷터로 사용한다
"editor.formatOnSave": true, // 파일이 저장될 때마다 코드 포맷터가 작동한다
"editor.codeActionsOnSave": { // 파일이 저장될때마다 eslint가 작동한다
"source.fixAll.eslint": true
},
"prettier.useEditorConfig": true // prettier에서는 editorconfig 에 따라 옵션을 설정한다
}
vscode에 prettier와 eslint 익스텐션을 설치하여 실시간으로 코드 포맷팅과 버그를 잡더라도,
때때로 버그가 있는 채로 commit을 할 수도 있습니다. 사람이라는건 완전하지 않기 때문입니다.
이에, git hook을 이용하여 commit하기 전에 자동으로 eslint 와 prettier를 동작시킨 후 error가 발생하지 않은 경우에만 commit이 가능하게 할 수 있습니다.
$ npx mrm lint-staged
※ 저의 컴퓨터로 vscode의 scm(source control manager) 사용시에는 git hook이 적용되지 않는 버그가 있었습니다. git output을 확인한 결과 can't find yarn in PATH: Skipping pre-commit hook
라는 log를 찾을 수 있었습니다.
분명히 터미널에서 확인한 PATH에는 yarn이 있는 곳의 PATH가 포함되어 있는데 말이죠.
$ which yarn
/home/dannykim/.nvm/versions/node/v14.15.4/bin/yarn
$ echo $PATH
/home/dannykim/bin:/home/dannykim/.nvm/versions/node/v14.15.4/bin:/usr/local/sbin:
/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
몇 번의 삽질결과, 터미널에서 직접 vscode를 실행하면 git hook이 실행되는 반면, 제가 미리 지정해둔 keyboard shortcut(Window + C)를 통해서 실행된 vscode에서는 git hook이 실행되지 않는 것을 확인하였습니다.
yarn이 위치한 /home/dannykim/.nvm/versions/node/v14.15.4/bin
은 ~/.zshrc
를 불러들이면서 PATH에 추가되는데, 구글링 결과 login shell은 ~/.profile
만을 불러들이며, ~/.zshrc
또는 ~/.bashrc
는 secondary interactive shells(bash, zsh)에서 불러들여진다는 것입니다. 따라서 keyboard shortcut으로 실행된 vscode는 login shell의 PATH가 적용되므로 /home/dannykim/.nvm/versions/node/v14.15.4/bin
이 포함되어 있지 않았던 것입니다.
아래와 같이 ~/.profile
을 설정하여 yarn이 위치한 곳을 PATH에 추가해주었더니 해결되었습니다.
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Difference between launching an application from a keyboard shortcut vs the terminal?
VSCode 짱짱짱!! 동동 블로그에 유익한 내용이 점점 추가되고 있어요! ㅋㅋㅋ😍😍