3. 코드 품질

protect-me·2021년 5월 31일
0
post-thumbnail

3.1 Chrome으로 디버깅하기


요약
스크립트 실행이 중단되는 경우는 다음과 같습니다.
중단점을 만났을 때
debugger문 만났을 때
에러가 발생했을 때(개발자 도구가 열려있고 버튼이 '활성화’되어있는 경우)
스크립트 실행이 중지되면 중단 시점을 기준으로 변수에 어떤 값이 들어가 있는지 확인할 수 있습니다. 또한 단계별로 코드를 실행해 가며, 어디서 문제가 발생했는지 추적할 수도 있습니다. 이런 식으로 디버깅이 진행됩니다.

디버깅(debugging)
스크립트 내 에러를 검출해 제거하는 일련의 과정을 의미

Chrome 개발자 도구
F12(MacOS: Cmd+Opt+I)

‘Sources’ 패널

  1. 파일 탐색 영역 – 페이지를 구성하는 데 쓰인 모든 리소스(HTML, JavaScript, CSS, 이미지 파일 등)를 트리 형태로 보여줌. Chrome 익스텐션이 여기 나타날 때도 있음
  2. 코드 에디터 영역 – 리소스 영역에서 선택한 파일의 소스 코드를 보여줌. 여기서 소스 코드를 편집할 수 있음
  3. 자바스크립트 디버깅 영역 – 디버깅에 관련된 기능을 제공

콘솔

Esc를 누르면 개발자 도구 하단부에 콘솔 창이 열림
여기에 명령어를 입력하고 Enter를 누르면 입력한 명령어가 실행 됨.

중단점

중단점(breakpoint) 은 말 그대로 자바스크립트의 실행이 중단되는 코드 내 지점을 의미

debugger 명령어

debugger;

  • 스크립트 내에 debugger 명령어를 적어주면 중단점을 설정한 것과 같은 효과
  • 에디터에서 중단점을 설정할 수 있기 때문에 편리

멈추면 보이는 것들

  1. Watch – 표현식을 평가하고 결과를 보여줌
  2. Call Stack – 코드를 해당 중단점으로 안내한 실행 경로를 역순으로 표시
  3. Scope – 현재 정의된 모든 변수를 출력(Local / Global)

실행 추적하기

  • ‘Resume’: 스크립트 실행을 다시 시작함 (단축키 F8)
  • ‘Step’: 다음 명령어를 실행함 (단축키 F9)
  • ‘Step over’: 다음 명령어를 실행하되, 함수 안으로 들어가진 않음 (단축키 F10)
  • ‘Step into’ (단축키 F11) : Step + 비동기 동작 무시)
  • ‘Step out’: 실행 중인 함수의 실행이 끝날 때 까지 실행을 계속함 (단축키 Shift+F11)
  • 모든 중단점을 활성화/비활성화
  • 예외 발생 시 코드를 자동 중지시켜주는 기능을 활성화/비활성화

console.log

console.log("here");


3.2 코딩 스타일


문법

중괄호

if (n < 0) {
  alert(`Power ${n} is not supported`);
}

가로 길이

백틱(`)을 사용하면 문자열을 여러 줄로 쉽게 나눌 수 있음

들여쓰기

  • 가로 들여쓰기: 스페이스 두 개 혹은 네 개를 사용해 만듦
  • 세로 들여쓰기: 논리 블록 사이에 넣어 코드를 분리해주는 새 줄

세미콜론

자바스크립트 엔진에 의해 무시되더라도 모든 구문의 끝엔 세미콜론을 써주는 것이 좋음

중첩 레벨

  • 가능하면 너무 깊은 중첩문은 사용하지 않도록 함
  • 반복문을 사용할 때 중첩문의 깊이가 깊어지면 continue 지시자를 쓰는 게 좋은 대안이 될 수도 있음
  • if/else와 return문을 조합하면 위 예시와 유사하게 중첩 레벨을 줄여 코드의 가독성을 높일 수 있음

함수의 위치

  1. 헬퍼 함수를 사용하는 코드 위에서 헬퍼 함수를 모아 선언하기
  2. 코드를 먼저, 함수는 그 다음에 선언하기 <= 지향
  3. 혼합: 코드 바로 위에서 필요한 헬퍼 함수 그때그때 선언하기

스타일 가이드

코딩 스타일 가이드는 코드를 '어떻게 작성할지’에 대한 전반적인 규칙을 담은 문서로, 어떤 따옴표를 쓸지, 들여쓰기할 때 스페이스를 몇 개 사용할지, 최대 가로 길이는 몇까지 제한할지 등의 내용을 담음

  • Google의 자바스크립트 스타일 가이드
  • Airbnb의 자바스크립트 스타일 가이드
  • Idiomatic.JS
  • StandardJS
  • 기타 등등

Linter

Linter라는 도구를 사용하면 내가 작성한 코드가 스타일 가이드를 준수하고 있는지를 자동으로 확인할 수 있고, 스타일 개선과 관련된 제안도 받을 수 있음

  • JSLint – 역사가 오래된 linter
  • JSHint – JSLint보다 세팅이 좀 더 유연한 linter
  • ESLint – 가장 최근에 나온 linter

ESLint 설치 방법

  1. Node.js를 설치합니다.
  2. npm(자바스크립트 패키지 매니저)을 사용해 다음 명령어로 ESLint를 설치합니다. npm install -g eslint
  3. 현재 작성 중인 자바스크립트 프로젝트의 루트 폴더(프로젝트 관련 파일이 담긴 폴더)에 .eslintrc라는 설정 파일을 생성합니다.
  4. 에디터에 ESLint 플러그인을 설치하거나 활성화합니다. 주요 에디터들은 모두 ESLint 플러그인을 지원합니다.
  5. .eslintrc 예시
{
  "extends": "eslint:recommended",
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "rules": {
    "no-console": 0,
    "indent": ["warning", 2]
  }
}

3.3 주석


요약
주석을 보면 좋은 개발자인지 아닌지를 어느 정도 알 수 있습니다. 주석을 언제 쓰고 언제 쓰지 않는지를 보면 되죠.
주석을 잘 작성해 놓으면 시간이 지난 후 코드를 다시 살펴볼 때 효율적으로 정보를 얻을 수 있습니다. 코드 유지보수에 도움이 되죠.

주석에 들어가면 좋은 내용

  • 고차원 수준 아키텍처
  • 함수 용례
  • 당장 봐선 명확해 보이지 않는 해결 방법에 대한 설명

주석에 들어가면 좋지 않은 내용

  • '코드가 어떻게 동작하는지’와 '코드가 무엇을 하는지’에 대한 설명
  • 코드를 간결하게 짤 수 없는 상황이나 코드 자체만으로도 어떤 일을 하는지 충분히 판단할 수 없는 경우에만 주석을 넣으세요.
  • 한 줄짜리 주석 : //
  • 여러 줄의 주석 : /* ... */

좋지 않은 주석

  • 좋은 코드엔 ‘설명이 담긴(explanatory)’ 주석이 많아선 안됨
  • “코드가 불분명해서 주석 작성이 불가피하다면 코드를 다시 작성해야 하는 지경에 이른 걸 수 있습니다.”

리팩토링 팁: 함수 분리하기

  • 함수 내 코드 일부를 새로운 함수로 옮기는 게 유익할 때도 있음

  • 함수 이름 자체가 주석 역할을 하므로 코드를 쉽게 이해할 수 있음 *자기 설명적인(self-descriptive) 코드

리팩토링 팁: 함수 만들기

  • 함수는 주석이 없어도 그 존재 자체가 무슨 역할을 하는지 설명할 수 있어야 함
  • 코드를 분리해 작성하면 더 나은 코드 구조가 됨
  • 가이드를 잘 지켜 코드를 작성하면 함수가 어떤 동작을 하는지, 무엇을 받고 무엇을 반환하는지가 명확해짐

좋은 주석

아키텍처를 설명하는 주석

  • 고차원 수준 컴포넌트 개요, 컴포넌트 간 상호작용에 대한 설명, 상황에 따른 제어 흐름 등

함수 용례와 매개변수 정보를 담고 있는 주석

  • JSDoc이라는 특별한 문법을 사용하면 함수에 관한 문서를 쉽게 작성할 수 있음(함수 용례, 매개변수, 반환 값 정보)

왜 이런 방법으로 문제를 해결했는지를 설명하는 주석

  1. 당신(혹은 동료)은 작성된 후 시간이 꽤 흐른 코드를 열어봅니다. 그리고 그 코드에서 선택한 방식이 ‘가장 좋은 방식은 아니란 걸’ 알아냅니다.
  2. "그때는 내가 멍청했구나. 하지만 지금은 더 똑똑해졌지"라고 생각하며, 이전보단 ‘더 명확하고 올바른’ 방법으로 코드를 개선합니다.
  3. 코드를 개선하려는 시도까지는 좋았습니다. 하지만 리팩토링 과정에서 '더 명확’하다고 생각했던 방법을 적용하면 문제가 발생한다는 걸 알아냅니다. 이미 시도해봤던 방법이기 때문에 왜 이 방법이 먹히지 않는지 희미하게 기억이 떠오릅니다. 새로 작성한 코드를 되돌렸지만, 시간이 낭비되었습니다.

미묘한 기능이 있고, 이 기능이 어디에 쓰이는지를 설명하는 주석


3.4 닌자 코드(지양할 코드)


코드 짧게 쓰기

조건부 연산자 ? 남발

글자 하나만 사용하기

let a, let b, let c ...

약어 사용하기

list → lst.
userAgent → ua.
browser → brsr.

포괄적인 명사 사용하기

obj, data, value, item, elem, data1, data2 ...

철자가 유사한 단어 사용하기

datedata같이 유사한 철자를 가진 단어를 조합

동의어 사용하기

displayMessage, showName, renderUser

이름 재사용하기

같은 이름의 변수명을 재사용함

재미로 언더스코어 사용하기

_name, __value

과장 형용사 사용하기

superElement, megaFrame, niceItem

외부 변수 덮어쓰기

let user = authenticateUser();

function render() {
  let user = anotherValue();
  ...

부작용이 있는 코드 작성하기

isReady(), checkPermission(), findTags() 등의 코드에 본래 기능을 넘어선 기능들을 추가하는 코드를 부여

함수에 다양한 기능 넣기

한 함수에 여러가지 기능 포함하기


3.5 테스트 자동화와 Mocha


요약
BDD에선 스펙을 먼저 작성하고 난 후에 구현을 시작합니다. 구현이 종료된 시점에는 스펙과 코드 둘 다를 확보할 수 있습니다.

스펙의 용도는 세 가지입니다.
1. 테스트 – 함수가 의도하는 동작을 제대로 수행하고 있는지 보장함
2. 문서 – 함수가 어떤 동작을 수행하고 있는지 설명해줌. describe와 it에 설명이 들어감
3. 예시 – 실제 동작하는 예시를 이용해 함수를 어떻게 사용할 수 있는지 알려줌
스펙이 있기 때문에 개발자는 안전하게 함수를 개선하거나 변경할 수 있습니다. 함수를 처음부터 다시 작성해야 하는 경우가 생겨도 스펙이 있으면 기존 코드와 동일하게 동작한다는 것을 보장할 수 있습니다.

코드가 바뀌어도 기존에 구현된 기능에 영향을 주지 않게 하는 건 대규모 프로젝트에서 매우 중요합니다. 프로젝트 규모가 커지면 함수 하나를 이곳저곳에서 사용하는데, 수동으로 변경된 함수가 이 함수를 사용하는 모든 곳에서 제대로 동작하는지 확인하는 건 불가능하기 때문입니다.
테스트를 하지 않고 코드를 작성해왔다면 개발자들은 둘 중 한 갈래의 길로 빠져버리고 맙니다.
아무 대책 없이 코드를 변경합니다. 부작용을 생각하지 않고 함수를 수정했기 때문에 어디선가 버그가 발생하고 맙니다.
수정이나 개선을 기피하게 됩니다. 버그의 대가가 가혹하기 때문이죠. 코드가 구식이 되어도 그 누구도 코드를 건드리려 하지 않습니다. 좋지 않은 상황이죠.
테스팅 자동화는 이런 문제를 피하게 도와줍니다!
테스팅 자동화를 수행하고 있는 프로젝트라면 이런 문제를 걱정하지 않아도 됩니다. 코드에 변화가 있어도 스펙을 실행해 테스트를 진행하면 몇 초 만에 에러 발생 여부를 확인할 수 있습니다.
장점이 하나 더 있습니다. 잘 테스트 된 코드는 더 나은 아키텍처를 만듭니다.
수정과 개선이 쉬우니까 당연히 좋은 아키텍처를 만들 수 있다고 생각할 수 있습니다. 하지만 또 다른 이유가 있습니다.
테스트를 작성하려면 함수가 어떤 동작을 하는지, 입력값은 무엇이고 출력값은 무엇인지 정의하고 난 후에 구현을 시작합니다. 코드는 정의된 사항을 뒷받침 할 수 있게 작성해야 하죠. 구현을 시작하는 순간부터 이미 좋은 아키텍처가 보장됩니다.
사실, 매번 이런 절차를 따라 구현한다는 게 쉽지만은 않습니다. 함수가 어떻게 동작해야 하는지 확신이 서지 않는 상황에서 코드를 작성하기도 전에 스펙을 작성해야 하므로 익숙하지 않을 수 있습니다. 그렇지만 테스트를 작성하면 일반적으로 개발 속도가 빨라지고 이전보다 코드를 더 안정적으로 작성할 수 있습니다.

테스트는 왜 해야 하는가?

  • 코드를 수동으로 ‘재실행’ 하면서 테스트를 하면 무언가를 놓치기 쉬움
  • 테스팅 자동화는 테스트 코드가 실제 동작에 관여하는 코드와 별개로 작성되었을 때 가능함 테스트 코드를 이용하면 함수를 다양한 조건에서 실행해 볼 수 있는데, 이때 실행 결과와 기대 결과를 비교할 수 있음.

Behavior Driven Development

BDD는 테스트(test), 문서(documentation), 예시(example)를 한데 모아놓은 개념

코드 실습 위주이기 때문에 블로깅을 생략함
링크에서 확인 요망 👉🏻 자세한 내용


3.5 폴리필


바벨

  • 바벨(Babel)은 트랜스파일러(transpiler)로, 모던 자바스크립트 코드를 구 표준을 준수하는 코드로 바꿔줌
  1. 트랜스파일러
    바벨은 코드를 재작성해주는 트랜스파일러 프로그램
    바벨은 개발자의 컴퓨터에서 돌아가는데, 이를 실행하면 기존 코드가 구 표준을 준수하는 코드로 변경됨
    변경된 코드는 웹사이트 형태로 사용자에게 전달
    웹팩(webpack)과 같은 모던 프로젝트 빌드 시스템은 코드가 수정될 때마다 자동으로 트랜스파일러를 동작시킴
    이런 과정이 없으면 개발이 끝난 코드를 한데 통합하는 데 어려움이 있을 수 있음

  2. 폴리필
    명세서엔 새로운 문법이나 기존에 없던 내장 함수에 대한 정의가 추가되곤 함
    새로운 문법을 사용해 코드를 작성하면 트랜스파일러는 이를 구 표준을 준수하는 코드로 변경해줌
    반면, 새롭게 표준에 추가된 함수는 명세서 내 정의를 읽고 이에 맞게 직접 함수를 구현해야 사용할 수 있음
    자바스크립트는 매우 동적인 언어라서 원하기만 하면 어떤 함수라도 스크립트에 추가할 수 있음
    물론 기존 함수를 수정하는 것도 가능
    개발자는 스크립트에 새로운 함수를 추가하거나 수정해서 스크립트가 최신 표준을 준수 할 수 있게 작업할 수 있음
    이렇게 변경된 표준을 준수할 수 있게 기존 함수의 동작 방식을 수정하거나, 새롭게 구현한 함수의 스크립트를 "폴리필(polyfill)"이라 부름
    폴리필(polyfill)은 말 그대로 구현이 누락된 새로운 기능을 메꿔주는(fill in) 역할
    - core js – 다양한 폴리필을 제공합니다. 특정 기능의 폴리필만 사용하는 것도 가능
    - polyfill.io – 기능이나 사용자의 브라우저에 따라 폴리필 스크립트를 제공해주는 서비스




📚 참고 : javascript.info

profile
protect me from what i want

0개의 댓글

관련 채용 정보