꼴도보기 싫었던 eslint를 적용시키다
< 꼴도보기 싫었던 eslint를 적용시키다 >
미루고 미뤄왔던 eslint를 드디어 적용하기 시작했다. 대략 6달 전에 하려고 시도 했을 때 파일 하나만 테스트 해 보았더니 js파일하나에 에러가 수천개 나는것 보고 어처구니가 없어서 바로 지웠었는데, 최근 같이 스터디 어떤분이 eslint 꼭 하라고 강추하길래 처음부터 차근차근 해보자 하고 조금씩 하기 시작했다. 작업해야할 javascript (React 포함하여) 쪽은 대략 50개 정도 .js가 있었고 대부분 4~500줄 이하의 간략한? 파일들이고 한 10개정도의 파일이 tyle의 핵심 엔진이 포함된 파일이라 1000~5000줄 짜리의 파일들이다.
3685줄의 코드에 6769개의 에러가 있는 충격적인 장면
< 3685줄의 코드에 6769개의 에러가 있는 충격적인 장면 >

정확히 저번주 금요일 3월2일 부터 시작된 lint 변환은 딱 8일 걸려 3월 9일로 끝이 났다. 처음 3일은 lint규칙을 알아가는 기간이라 시간이 굉장히 오래걸렸지만 어느정도 규칙들을 파악하기 시작했고, 4일째 부턴 스피드 하게 진행 되어 6일째에 변환 작업은 거의 끝이 났다. 하지만 다 변환하고 보니, 어처구니 없는 오타들과 작동오류(arrow functionthis 등등) phantomjs와의 호환성문제 때문에 추출불가 등등 이전의 tyle과 동일하게 적용시키기 위한 오류수정에 2일이 걸렸다. 아 참고로 코드스타일은 취향차이라곤 하지만 airbnb가 이렇게 한다. 그러니 이렇게 습관을 바꾸면 된다. 사실 lint자체가 다 취향이긴하지만 모든것은 가독성을 위한 것이고 실제로 eslint airbnb 스타일로 바꾸니 가독성이 좋아진것 같은 느낌이 든다. 그리고 es6의 대한 설명은 따로 하지 않는다. 이 글은 es6의 문법을 알리는것이 아니다, 그리고 사실 자세히 파면 나도 잘 모른다.

대충 이정도로 하고 잡설은 끝내고 본격적으로 eslint airbnb 룰대로 변환시키며 내가 느낀 팁들을 공유해보려한다.

-

기본

1. var로 선언했던 변수들은 const, 그중에서 재정의될 변수는 let으로 정의한다.

const aa = {
    a: 2,
    b: 3
}
aa.a = 5;

이것은 가능할까? 난 당연히 안될줄 알았지만 된다. aa를 재정의 한것이 아닌 aa안의 a라는 property의 속성을 바꾼것이므로 인정. 하지만

aa = { a: 5};

이것은 aa를 재정의 한것이라 엔진에서 인정하지 않는다. 생활코딩 강의에서 들었는데, lint변환할때 우선 var를 모조리 const로 바꾼뒤 lint에서 let으로 바꾸라고 에러 뜨는 놈만 let으로 바꾸는 방법을 아주 요긴하게 썻다. (생각보다 const가 훨씬 많았다.)

2. elseif가 들어갈경우 else if로...

if (a) {
} else {
    if (b) { // 이런거 노노
    } else {
    }
}

else안의 if 문을 else if로 넣어라.

if (a) {
} else if (b) {
} else {
}

이것은 좀 의아했다. 왜냐면 tyle 로직상 else안에 또 if나 그 안에 다시 if가 있는 부분이 가끔 있는데 이것을 저렇게 올려버리면 로직이 꼬일것 같아서 일단 rule에서 걸렸었는데, 막상 바까보니 로직은 전혀 이상이 없었따.

3. 다중삼항연산식은 if로 빼거라

const haha = a === 'a' ? 1 : (a === 'b' ? 1 : 2);

뭐 이런것들? 삼형연산안에 또다시 삼항연산이 있고 어쩔땐 그안에 또 있을수도있지만 1단계 관문도 점점 알아보기 힘들어지는데 2단계관문으로 가면 슬슬 열받는다. 하지만 내가 짠 코드중에도 이중삼항연산이 상당히 많아서 이것들 모두 if로 변환했다. 다중삼항연산식으로 한줄로 짠 코드가 if로 인해 소스가 길어지겠지만 먼 훗날 다시 코드를 볼때 이해하는 시간을 줄여준다.

4. Template Strings

뭐 이건 es6에서 나온것이라 잘 쓰고 있었는데, 모든 '' + 변수 를 template strings로 바꾸는데에 많은 애를 먹었다. 기존 껀 ' '따옴표와 +플러스가 난발되어있어서 연산식이었던 것을 지워버려가지고 로직이 꼬인적도 많았다. 잘보고 해야한다.

haha + '호옹이' + hello;
// '' 와 + 조합을 backquote로 감싸자.
`${haha}호옹이${hello}`;

5. let은 multiple declare이 안됨

multiple declare는 잘쓰고 있었는데 좀 아쉽지만 어쩔수 없지..

let aoeu = '', // (쉼표쓴뒤 다음 변수에 let을 안쓰는..)
    uuu = ''; // 이거 안되고,

let aoeu = ‘’;
let uuu = ‘’;
// 각각 선언하시오.

6. arrow function을 할것이 아니라면 annonymous로 만들지 말고 이름을 붚혀롸!

const aa = function() {
    // 이렇게 말고
}
const aa = function aa () {
    // annonymous더라도 꼭 함수에 이름을 붙혀라. 다신 안쓰더라도 이름을 붙혀라 이름을
}

7. HTML에서 string만 있을땐 “” 쌍따옴표

javascript관련 문자는 ‘’ 따옴표

<div class="나는 HTML부분 이기 때문에 쌍따옴표">
const aa = '나는 javascript string이기 때문에 홑따옴표'; 

세미콜론

함수가 아닌이상 (if 나 for문) 세미콜론(;)을 붙히지 말라 (스위치나 기타등등 포함) 난 습관적으로 모든 닫히는 } 구간에 세미콜론을 넣는 버릇이 있었다. 내가 짠 코드가 아님에도 왠지 있어야할것같아서 세미콜론을 넣었는데 이게 아니었다.

if () {
}; // <- 세미콜론 붙히지 말라.
for (){
}; // 마찬가지

띄어쓰기

1. 변수 선언이나 할때 반드시 = 양옆에 띄어쓰기 너무 당연한것이지만 가끔 귀찮을때가 있다.

const a = 1;
const a=1; 이거 안됨

그리고 당연히 default function params에서도 적용

aoeu(aaa = 1, bbb = {}) {
}

2. 그리고 연산자 앞뒤로도 반두시 띄어쓰기를 해주어야 한다.

a = 1+2; // 에러
a = 1 + 2; // 통과
a+=1; // 에러
a += 1; // 통과

3. 그리고 한가지 더 말하자면 함수에서 ()소활호와 {중괄호와 사이에는 반드시 띄어쓰기가 있어야 한다.

aoeu()여기{
}

당연히 if else도 마찬 가지다

if () {
    // if와 else if 괄호 양옆에 반드시 띄어쓰기
} else if () {

} else {
    //물론 else도 예외는 없다.
}

for문도 역시

for () {
}

5. parameter나 배열 등등 , 를 써야 할 상황이 온다면 반드시 쉼표 뒤에 띄어라

[1,2,3,4];  // ㄴㄴ
[1, 2, 3, 4]; 

6. 주석엔 항상 탭이나 띄어쓰기를 쓰도록 (띄어쓰기가 좋은듯)

//하하 ㄴㄴ
// 하하 

7. 절대로 빈칸을 만들지 마시오

보이지 않는 띄어쓰기 때문에 엄청난 에러가 난다.
< 보이지 않는 띄어쓰기 때문에 엄청난 에러가 난다. >

주석에도 마찬가지다

// 하하(띄어쓰기) <- 이런거 안된다.

8. 그리고 마지막으로 아래 짧은 구문안에 몇개의 lint에러가 있을까?

{'haha' : 'haha', 'babo' : 'b'}

아주 놀랍게도 3개의 에러를 뿜는다. 첫번째 에러 = 객체 중괄호사이에는 반드시 띄어쓰기를 해야한다.

{여기'haha' : 'haha', 'babo' : 'b' 여기}

두번째 에러 = key는 ' 따옴표가 필요없다.

{ haha : 'haha', babo : 'b' }

세번째 에러 key를 쓴뒤 땡땡(:)사이엔 띄어쓰기를 하면 안된다.

{ haha(띄어쓰기가 있으면 안됨): 'haha', babo(띄어쓰기가 있으면 안됨): 'b' }
{ haha: 'haha', babo: 'b' }

네번째 에러 key와 value가 같으면 하나만 써도 되는 뭐 그런건데 이건 바로 아래서 아주 간단히 써놓을것이다. 결과 :

{ haha, babo: 'b' }

줄여쓰기

1. property shorthand라고 하는데, 쉽게 말해 object에서 key 와 value가 같으면 하나만 써라이다.

const aa = {
    haha: haha, // 이렇게 말고
    haha // 이렇게
};

2. 삼항식 쓸때 결과가 true or false인 경우 쓸필요 없다.

let a = 1 > 2 ? true : false // 이런거나
let a = b === ‘’ ? true : false  이런거 노
let a = 1 > 2; // 라고만 써도 a는 false가 들어간다.

너무나도 당연한 것이지만 변환하면서 보니깐 내가 이렇게 쓴 부분들이 생각보다 많았다.

3. i++, i-- 이런거 노 i += 1

이것은 의아해했던 부분인데 까라면 까야한다 airbnb이기때문에 그리고

i = i*3; // 이런것도 노노 
i *= 3; 이렇게 써야한다. 

괄호

1. 연산식이 두개 이상 있으면 반드시 괄호를 씌워주자

1 * 2 + 3; 

이런것은 당연히 1 * 2을 괄호를 씌워주는건 기본이다. (어찌보면 곱셈연산이 앞에 있기 때문에 괄호가 필요가 없지만 lint규칙에서 필수) 근데 더 웃긴건

1 + 2 + 3;

이것도 괄호를 씌워주어야 한다는것이다. 도저히 이해가 안되서 이 rule은 같은 level의 연산 ( +, - 이나 *, /)만 있는 구문은 허용을 하게 했다. 즉 위에 예시에서

1 + 2 + 3; 허용
1 * 2 + 3; 에러 // -> (1 * 2) + 3; 이렇게 바꿔주는 것 정도로만 타협했다. 너무 쓸데없이 룰이 강력함 

2. switch case 에 {}

switch() {
    case: { // 여기에 중괄호를 넣어야 한다는것은 처음 알았다. 그리고 중괄호가 들어갈 수 있다는것 자체도 몰랐다.
        break;
    }
    default: {
        // 디폴트는 필수임 안쓰면 온갖에러가 나기때문에 아무것도 없다라도 일단 써주자
    }
}

3. arrow function때 parameter에 괄호는 2개이상일때부터 괄호를 씌우자

const aa = () => {
    // param이 없으면 그냥 괄호
};
const aa = haha => {
    // parameter가 하나라면 괄호를 쓰면 안된다 (안되는건 아니고 쓰지 않는것이 좋다 라고 airbnb가 말했다.)
};
const aa = (haha, kikiki) => {
    // parameter가 2개 이상이라면 괄호로 씌워주자
};

이정도가 끝이다. 규칙은 어마어마하게 많지만 내가 기억나고 기억에 남아 evernote에 썻던 내용들이다.