해당 코딩 컨벤션은 회사 동료분과 함께 정의한 코딩 컨벤션입니다.
구글링을 통해 toast.ui의 컨벤션을 베이스로, 일을 하며 느꼈던 점을 반영해 저희 팀만의 컨벤션을 정의 했습니다.
기본적으로 프로젝트에 ESLint 규칙과 Prittier 의 포멧팅이 반영되어 있지만, 개발자가 지켜야할 프론트엔드 파트의 컨벤션을 정의했습니다.
좋은 코드 퀄리티와 원활한 프론트엔드 개발자의 협업을 위해서 아래의 코딩 컨벤션을 준수해주시기 바랍니다.
var text = '123';
var html = '<a href="#">link</a>';
var style = {
'left': '100px',
'top': '100px'
}
// Bad
const BunYukByunSoo = '번역변수';
// Good
<div></div>
// Bad
<DIV></DIV>
const THIS_IS_CONSTANT = 'string';
interface Props {
onClick: (event) => void;
}
function Component(props: Props) {
return <></>;
}
const Component = (props: Props) => <></>;
function Component(props) {
const handleClick = (event) => console.log(event);
return <></>;
}
const isNotBoolean = false; // 옳지 않은 선언
cosnt isBoolean = true; // 옳은 선언
const canOpen = true;
const hasChildren = true;
// 잘못된 선언
enum FORM_MODE {
CREATE = 'create',
EDIT = 'edit',
ADD = 'add',
}
// 컨벤션을 지킨 선언
enum FormMode {
Create = 'create',
Edit = 'edit',
Add = 'add',
}
// Bad Case
interface IServer {
title: string;
value?: string;
}
// Good Case
interface Server {
sample: string;
}
function Component(props) {
return (<div></div>);
}
type Props = {
children: React.ReactNode;
}
function Component(props: Props) {
return <div>{props.children}</div>;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const textFieldCss = css`
font-size: 14px;
`;
const Wrapper = styled.div``;
cosnt FormRow = styled.section``;
// 기본적으로 .을 사용함
className={styles.test}
// class name에 - 이 포함될 경우 아래와같이 사용
className={styles[‘test-test’]}
# 선언예시
// Good
var emptyArr = [];
var arr = [1, 2, 3, 4, 5];
// Bad
var emptyArr = new Array();
var arr = new Array(1, 2, 3, 4, 5);
# 복사예시
var items = [1, 2, 3, 4];
var len = items.length;
var itemsCopy = [];
// Bad
for (var i = 0; i < len; i++) {
itemsCopy[i] = items[i];
}
// Good
const arr = [...items];
// Good
var emptyObj = {};
var obj = {
pro1: 'val1',
pro2: 'val2'
};
// Bad - 객체 생성자 사용
var emptyObj = new Object();
var obj = new Object();
// Good(1)
function doSomething(param1, param2) {
return param1 + param2;
}
// Good(2)
var doSomething = function(param1, param2) {
return param1 + param2;
};
// Good(3) - 이름있는 함수 표현식
var doSomething = function doSomething(param1, param2) {
return param1 + param2;
};
// Bad(1) - 함수 생성자 사용
var doSomething = new Function('param1', 'param2', 'return param1 + param2;');
// Bad(2) - IIEF
(function() {
...
}());
// Good
[1, 2, 3].map(x => {
const y = x + 1;
return x * y;
});
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
[1, 2, 3].map(number => `A string containing the ${number}.`);
function Template({var, const, ...args}) {
cosnt A = var;
};
const arr = [1, 2, 3, 4];
// Good
const [first, second] = arr;
// Bad
const first = arr[0];
const second = arr[1];
// Good
function sayHi(name) {
return `How are you, ${name}?`;
}
// Bad
function sayHi(name) {
return 'How are you, ' + name + '?';
}
// Bad
function sayHi(name) {
return ['How are you, ', name, '?'].join();
}
// Good(1)
if (string) ...
// Bad
if (string !== "") ...
// Good(1)
if (array.length) ...
// Bad
if (array.length > 0) ...
if (Object.keys(object).length) ...
// Good(1)
if (!string) ...
// Bad
if (string === '') ...
// Good(1)
if (!array.length) ...
// Bad
if (array.length === 0) ...
// Good
if (variable) ...
// Bad
if (variable === true) ...
// Good
if (!variable) ...
// Bad
if (variable === false) ...
// Good
function getResult() {
var resultData;
if (condition) {
resultData = someDataInTrue;
} else {
resultData = someDataInFalse
}
return resultData;
}
// Allow
function foo(isValid) {
if (!isValid) {
return;
}
return someDataInTrue;
}
// Bad
function getResult() {
if (condition) {
return someDataInTrue;
}
return someDataInFalse;
}
const array = [1, 2, 3];
// Good
array.forEach((number) => {...});
// Bad
for (var i = 0; i < array.length; i++) ...
// Worse
for (var i in array) ...
// Good
Object.keys(object).forEach(key => {...});
// Bad
var key;
for (key in object) ...
// Good
var value;
if (typeof str === 'string') {
value = (a + b);
}
// Bad
var value;
if(typeof str==='string') {
value=(a+b);
}
// Good
var arr = [1, 2, 3, 4];
// Good
someFunction(a, b, {
prop1: 1,
prop2: 2,
prop3: 3
});
// Bad - 괄호 안에 공백
if ( typeof str === 'string' )
// Bad - 괄호 안 공백, 콤마 뒤 공백 없음
var arr = [ 1,2,3,4 ];
// Bad - 객체의 닫는 괄호 다음에 개행
someFunction(a, b, {
prop1: 1,
prop2: 2,
prop3: 3
}
);
condition ? 'a' : 'b'
const data = undefined;
const result = a ?? 'a'; // a 가 undefined 이거나 null 일 경우 'a' 를 리턴
const { data: subscription } = useSubscription();
<div>{subscription?.count}</div>
// Good
const condition = !!array.length;
// Bad
const conditon = new Boolean(array.length);
const number = Number('1');
cosnt number = +'1';
// Bad
if (condition) return;
// Good
if (condition) {
return;
}
//[문자열]
typeof variable === 'string'
//[숫자]
typeof variable === 'number'
//[불린]
typeof variable === 'boolean'
//[객체]
typeof variable === 'object'
//[배열]
Array.isArray(arrayObject)
//[널 Null]
variable === null
//[미할당 Undefined]
typeof variable === 'undefined'
variable === undefined
//[null || undefined]
variable == undefined
//[엘리먼트 노드]
element.nodeType === 1