HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🧚
[1기]최종 프로젝트 데브코스
/
🪙
[팀1] 도깨비
/
🔰
금뚝 기획서
/
❓
ESlint 규칙 파헤치기
❓

ESlint 규칙 파헤치기

자기 참조 할당은 하지 않는다.

no-self-assign
자기 참조는 효과가 없으며, 불완전한 리팩터링으로 인한 오류일 수 있다.
참고 ESLint - no-self-assign
// Bad foo = foo; [a, b] = [a, b]; [a, ...b] = [x, ...b]; ({a, b} = {a, x}); // Good foo = bar; let foo = foo; [foo = 1] = [foo];

배열과 객체

배열과 객체는 반드시 리터럴로 선언한다.

no-new-object
리터럴 표기법은 생성자 함수보다 짧고 명확하며 실수를 줄일 수 있다.
참고 ESLint - no-new-object
// Bad const emptyArr = new Array(); const arr = new Array(1, 2, 3, 4, 5); // Bad - 객체 생성자 사용 const emptyObj = new Object(); const obj = new Object(); // Good const emptyArr = []; const arr = [1, 2, 3, 4, 5]; // Good const emptyObj = {}; const obj = { pro1: 'val1', pro2: 'val2' };

배열 복사 시 순환문을 사용하지 않는다.

Spread Operator
복잡한 객체를 복사할 때 전개 연산자를 사용하면 좀 더 명확하게 정의할 수 있고 가독성이 좋아진다.
참고 mdn – Spread Operator
const len = items.length; let i; // Bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // Good const itemsCopy = [...items];
ES5의 환경에서는 Array.prototype.slice를 사용한다. (ES5)
// Good itemsCopy = items.slice();

객체의 메서드 표현 시 축약 메소드 표기를 사용한다.

object-shorthanded
복잡한 객체 리터럴을 보다 명확하게 정의할 수 있다.
참고 ESLint - object-shorthanded
// Bad const atom = { value: 1, addValue: function(value) { return atom.value + value; } }; // Good const atom = { value: 1, addValue(value) { return atom.value + value; } };

메서드 문법 사용 시 메서드 사이에 개행을 추가한다.

lines-between-class-members
참고 ESLint - lines-between-class-members
// Bad class MyClass { foo() { //... } bar() { //... } } // Good class MyClass { foo() { //... } bar() { //... } }

함수

함수는 사용 전에 선언해야 하며, 함수 선언문은 변수 선언문 다음에 오도록 한다.

함수 표현식으로 생성된 함수는 호이스팅 시 값이 할당되지 않으므로 선언 이전에 사용하면 오류가 발생한다.
// Bad - 선언 이전에 사용 const sumedValue = sum(1, 2); const sum = function(param1, param2) { return param1 + param2; }; // Bad - 선언 이전에 사용 const sumedValue = sum(1, 2); function sum(param1, param2) { return param1 + param2; }; // Good const sum = function(param1, param2) { return param1 + param2; }; const sumedValue = sum(1, 2);

화살표 함수

함수 표현식 대신 화살표 함수를 사용한다.

prefer-arrow-callback
화살표 함수는 별도의 this 바인딩 없이 상위 컨텍스트에 바인딩되기 때문에 함수 표현식보다 혼란이 적으며 덜 장황하고 추론이 쉽다.
참고 ESLint - prefer-arrow-callback
// Bad [1, 2, 3].map(function (x) { const y = x + 1; return x * y; }); // Good [1, 2, 3].map(x => { const y = x + 1; return x * y; });

화살표 함수의 파라미터가 하나이면 괄호를 생략한다.

arrow-parens
파라미터가 하나일 때 괄호를 생략하면 화살표 함수의 장점을 살릴 수 있다.
참고 ESLint - arrow-parens
// Bad [1, 2, 3].map((x) => { const y = x + 1; return x * y; }); // Good [1, 2, 3].map(x => x * x); // Good [1, 2, 3].reduce((y, x) => x + y);

암시적 반환을 사용할 경우 함수 본문 전에 개행을 하지 않는다.

implicit-arrow-linebreak
실수로 인한 return문 누락과 암시적 반환을 판단하는데 혼란을 피할 수 있다.
참고 ESLint - implicit-arrow-linebreak
// Bad (foo) => bar; (foo) => (bar); (foo) => bar => baz; // Good (foo) => bar; (foo) => (bar); (foo) => bar => baz; (foo) => ( bar() );

템플릿 문자열

변수 등을 조합해서 문자열을 생성하는 경우 템플릿 문자열을 이용한다.

자바스크립트에서 문자열을 보다 쉽고 명확하게 다룰 수 있어 코드 복잡도가 낮아진다.
prefer-template
참고 ESlint - prefer-template
// Bad function sayHi(name) { return 'How are you, ' + name + '?'; } // Bad function sayHi(name) { return ['How are you, ', name, '?'].join(); } // Bad - 일반적인 경우, 홑따옴표를 사용 function sayHi(name) { return `How are you name?`; } // Good function sayHi(name) { return `How are you, ${name}?`; }

모듈

항상 import와 export를 이용한다.

다른 모듈 로드 방법과 혼용하여 사용하면 코드의 일관성이 없어진다.
// Best import {es6} from './AirbnbStyleGuide'; export default es6; // Bad const AirbnbStyleGuide = require('./AirbnbStyleGuide'); module.exports = AirbnbStyleGuide.es6; // Good import AirbnbStyleGuide from './AirbnbStyleGuide'; export default AirbnbStyleGuide.es6;

wildcard import는 사용하지 않는다.

with문법을 지양해야 하는 것과 같은 이유로, 이름을 지정하지 않으면 모듈이 변경될 때마다 식별자 충돌이 발생할 수 있다.
// Bad import * from './AirbnbStyleGuide'; // Good import * as AirbnbStyleGuide from './AirbnbStyleGuide';

import문으로부터 직접 export하지 않는다.

한 줄로 표현되어 간결하기는 하지만, import와 export 하는 방법을 명확하게 구분함으로써 일관성을 유지하자.
// Bad export {es6 as default} from './airbnbStyleGuide';

블록 구문

한 줄짜리 블록일 경우라도 {}를 생략하지 않으며 명확히 줄 바꿈 하여 사용한다.

한 줄짜리 블록일 경우 {}를 생략할 수 있지만, 이는 코드 구조를 애매하게 만든다. 당장은 두 줄을 줄일 수 있겠지만 이후 오류 발생 확률이 높아 잠재된 위험 요소가 된다.
참고 ESLint - brace-style ESLint - curly
// Bad if(condition) doSomething(); // Bad if (condition) doSomething(); else doAnything(); // Bad for(let prop in object) someIterativeFn(); // Bad while(condition) iterating += 1; // Good if (condition) { ... } // Good if (condition) { ... } else { ... }

키워드와 조건문 사이에 빈칸을 사용한다.

키워드와 조건문 사이가 빼곡하면 코드를 읽기 어렵다.
참고 ESLint - keyword-spacing
// Bad var i = 0; for(;i<100;i+=1) { someIterativeFn(); } // Good var i = 0; for (; i < 100; i += 1) { someIterativeFn(); }

do-while문 사용 시 while문 끝에 세미콜론을 쓴다.

// Bad do statement while(condition) // Good do { ... } while (condition);

switch-case 사용 시 첫 번째 case문을 제외하고 case문 사용 이전에 개행한다.

// Good switch (value) { case 1: doSomething1(); break; case 2: doSomething2(); break; case 3: return true; default: throw new Error('This shouldn\'t happen.'); }

switch-case 사용 시 각 구문은 break, return, throw 중 한 개로 끝나야 하며 default문이 없으면 // no default 표시를 해준다.

여러 케이스가 하나의 기능을 한다면 break를 생략해도 좋지만, 조금이라도 다른 기능을 포함한다면 break를 생략하지 말고 다른 방식으로 코드를 수정한다.
참고 ESLint - no-fallthrough
// Bad - 케이스 1 과 2 가 서로 다른 처리를 하지만 break가 생략됨 switch (value) { case 1: doSomething1(); case 2: doSomething2(); break; case 3: return true; // no default } // Bad - default문이 없지만 아무런 표기가 없음 switch (value) { case 1: doSomething1(); break; case 2: doSomething2(); break; case 3: return true; } // Good - 여러 케이스가 하나의 처리를 할 때는 break생략 허용 switch (value) { case 1: case 2: doSomething(); break; case 3: return true; // no default }

데이터형 확인하기

미리 약속된 데이터형 확인법을 사용한다. → proptypes 사용

미리 약속한 판별법으로 코드를 예측하기 쉽도록 한다. FE개발랩의 코드 유틸리티인 Toast UI CodeSnippet사용을 권장한다.
// 문자열 typeof variable === 'string' tui.util.isString(variable) // 숫자 typeof variable === 'number' tui.util.isNumber(variable) // 불린 typeof variable === 'boolean' tui.util.isBoolean(variable) // 객체 typeof variable === 'object' tui.util.isObject(variable) // 배열 Array.isArray(arrayObject) tui.util.isArray(variable) // 널 Null variable === null tui.util.isNull(variable) // 미할당 Undefined typeof variable === 'undefined' variable === undefined tui.util.isUndefined(variable) // 엘리먼트 노드 element.nodeType === 1 tui.util.isHTMLNode(element)

조건 확인하기

삼중 등호 연산자인 ===, !==만 사용한다. [eqeqeq]

==이나 !=는 암묵적 캐스팅으로 타입에 관계없이 판단되어 조건문의 의도를 파악하기 어렵고 버그로 이어진다.
참고 ESLint - eqeqeq
const numberB = 777; // Bad if (numberB == '777') { ... } // Good if (numberB === 777) { ... }

미리 약속된 조건 확인법을 사용한다.

미리 약속한 판별법을 사용하면 코드를 예측하기 쉽다. FE개발랩에서 만든 코드 유틸리티인 Toast UI CodeSnippet을 사용하는 것을 권장한다.
// 문자열 - 빈 문자열이 아닌가? if (string) ... // 문자열 - 빈 문자열인가? if (!string) ... // 배열 - 순회할 요소가 있는가? if (array.length) ... // 배열 - 빈 배열인가? if (!array.length) ... // 객체 - 순회할 속성이 있는가? if (Object.hasOwnProperty) ... // 객체 - 빈 객체인가? if (tui.util.isEmpty(object)) ... // 할당된 값이 있는가? if (tui.util.isExisty(variable)) ... // 참조변수가 참(true)인가? if (variable) ... // 참조변수가 거짓(false)인가? if (!variable) ...

반환하기

return문 바로 위는 한 칸 비워 놓는다. [newline-before-return]

다른 명령과 return문이 붙어있으면 가독성이 좋지 않으므로 return문 전에 한 줄 띄운다
참고 ESLint - padding-line-between-statements
// Bad function getResult() { ... return someDataInFalse; } // Good function getResult() { ... return someDataInFalse; }

주석

주석은 설명하려는 구문에 맞춰 들여쓰기 한다.

// Bad function someFunction() { ... // statement에 관한 주석 statements } // Good function someFunction() { ... // statement에 관한 주석 statements }

문장 끝에 주석을 작성할 경우, 한 줄 주석을 사용하며 공백을 추가한다.

// Bad var someValue = data1;//주석 표시 전후 공백 // Bad var someValue = data1; /* 여러 줄 주석 */ // Good var someValue = data1; // 주석 표시 전후 공백

여러 줄 주석을 작성할 때는 의 들여쓰기를 맞춘다. 주석의 첫 줄과 마지막 줄은 비워둔다.

// Bad - '*' 표시의 정렬 /* * 주석내용 */ // Bad - 주석의 첫 줄에는 기술하지 않는다 ... /* var foo = ''; * var bar = ''; * var quux; */ // Good - '*' 표시의 정렬을 맞춘다 /* * 주석내용 */

코드 블럭 주석 처리를 위해서는 한 줄 주석을 사용한다.

// Bad - 여러 줄 주석을 사용 ... /* * var foo = ''; * var bar = ''; * var quux; */ // Good - 한 줄 주석 사용 ... // var foo = ''; // var bar = ''; // var quux;

공백

키워드, 연산자와 다른 코드 사이에 공백이 있어야 한다. [keyword-spacing]

빼곡한 연산자와 키워드가 있는 코드는 읽기 어렵다.
// Bad var value; if(typeof str==='string') { value=(a+b); } // Good var value; if (typeof str === 'string') { value = (a + b); }

시작 괄호 바로 다음과 끝 괄호 바로 이전에 공백이 있으면 안 된다.

[object-curly-spacing] []
➡️
구조분해 할당과의 설정 충돌? 링크
// Bad - 괄호 안에 공백 if ( typeof str === 'string' ) // Bad - 괄호 안 공백 var arr = [ 1, 2, 3, 4 ]; // Good if (typeof str === 'string') { ... } // Good var arr = [1, 2, 3, 4];

콤마 다음에 값이 올 경우 공백이 있어야 한다.

콤마로 구분된 아이템 간에 간격을 두면 가독성이 향상된다. FE개발랩에서는 콤마 바로 뒤에 공백을 추가한다.
// Bad - 콤마 뒤 공백 var arr = [1,2,3,4]; // Good var arr = [1, 2, 3, 4];

맺음말

지금까지 코딩 컨벤션에 대해 알아보았다. 코딩 컨벤션은 자바스크립트 프로젝트에서 선택이 아닌 필수로 가지고 있어야 하는 코딩 스타일 규약이다. 이 가이드는 FE개발랩에서 사용하는 자바스크립트의 기본 스타일 규칙을 문서화했다. 사용하는 프레임워크와 프로젝트 성격에 따라 더 상세한 코딩 컨벤션을 적용할 수 있다. 이 가이드가 가독성 좋고 관리가 용이한 코드를 작성하는데 도움이 되길 바란다.
번호
규칙명
내용
1
object-curly-spacing
시작 괄호 바로 다음과 끝 괄호 바로 이전에 공백이 있으면 안 된다.
2
keyword-spacing
키워드, 연산자와 다른 코드 사이에 공백이 있어야 한다.
3
newline-before-return
return문 바로 위는 한 칸 비워 놓는다.
4
eqeqeq
삼중 등호 연산자인 ===, !==만 사용한다.
5
prefer-template
변수 등을 조합해서 문자열을 생성하는 경우 템플릿 문자열을 이용한다.
6
implicit-arrow-linebreak
암시적 반환을 사용할 경우 함수 본문 전에 개행을 하지 않는다.
7
arrow-parens
화살표 함수의 파라미터가 하나이면 괄호를 생략한다.
8
prefer-arrow-callback
함수 표현식 대신 화살표 함수를 사용한다.
9
lines-between-class-members
메서드 문법 사용 시 메서드 사이에 개행을 추가한다.
10
object-shorthanded
객체의 메서드 표현 시 축약 메소드 표기를 사용한다.
11
no-var
var 변수를 사용하지 않는다.
12
no-self-assign
자기 참조 할당은 하지 않는다.