최근 들어 팀을 옮기게 되면서.. 드디어. 내가 원하던 Node.js개발을 업무로 담당하게 되었다.

사실 옮기기전에 해당 Repo의 소스코드를 면밀히 분석하고 결정했는데. 무엇보다도 마음에 들었던 부분은 해당 코드가 ES6로 전환하는 중이였고 대부분의 코드가 ES6 기준으로 작성되어있는 부분이였다.( +로 js 로 fe/be 모두 구성되어있다는 점도 매력적 ) (사실 서비스 릴리즈가 급박한 이전 팀 상황에서는 기존 레가시 코드를 ES6로 바꾸기가 만만치 않았다. 물론 신규로 작성되는 페이지는 나도 ES6를 작성하고 있었지만. 신규 페이지는 잘 없고 거의 유지/보수/운영 업무라 ES5로 코딩하는 비율이 70%는 넘었다.  )

그런데 신기한 점은 물론 외부에 오픈된 서비스는 아니지만 해당 Node.js 버전이 7.x 버전을 사용하고 있었다는 점이였다. 이 이유에 대해 알아보니 ES6를 babel없이 사용하고 싶어서 였는데. 문득 궁금해졌다.

과연 Node.js 의 어느 버전까지 es6를 babel과 같은 syntax transformers 도구에 의지 안하고 마음껏(?) 사용할 수 있을까?

결론은 http://node.green/ 를  참고하면 버전을 선택하는 의사결정에 도움이 될것 같다.

1

해당 사이트의 제일 위 화면을 캡쳐한것인데 쓰고싶은 es6 feature에 대해 어느 버전의 Node.js 가 어디까지 지원하는지 확인할 수있다.

결론적으로.  6.10.1 버전과 7.5 버전은 es6 를 사용하는데 차이가 없으며. 만약 쓰고자하는 feature가 es6 중에 일부분이라면 ( 주로 공개된 arrow, let,const, class, rest parameter, 등이라면 ) 6.4.0도 괜찮은 선택이고 LTS 인 6.10.1 버전을 쓰는게 외부에 오픈된 서비라면 더 나은 선택일 수도 있다.

물론 개인적인 의견으로는 요즘 webpack2 가 너무나도 좋게 컴파일을 해주고 있기 때문에.. babel을 웬만하면 쓰는게 좋을것 같다. (기존 레가시가 없다면..)

해당 포스트는 사실 제작년에 알았던 이슈이고..
작년에 팀분들과 이야기 하다가 정리했던 이슈인데 작성만 해놨다가 이제야 올리게 된다. ( 반성..)

그래도 나름 신기했던 동작이였고, 나중에 누군가에게는 도움이 될것 같아서 정리해둔다.

보통 HTML5 에서는 checked, selected, disabled, readonly 등의 attribute 를 사용할때 아래와 같이 쓰게 된다.

 <input type="checkbox" checked> <!-- 이렇게 쓰는걸 선호함 -->
 <input type="checkbox" checked="checked">

위에서 checked attribute 만 선언 하는것은

아래의 코드는 기본적으로 HTML5 에서 동일하게 취급되기 때문이다.

 <input type="checkbox" checked>
 <input type="checkbox" checked="">
 <input type="checkbox" checked="checked">

이 이유는 checked attribute 는 boolean attribute 이기 때문이기도 한데 추가하자면 XHTML에서는 checked=”checked” 가 유효하지만 HTML5에서는 같은 결과를 내기 때문에 checked 하나만 쓰게 된다.
프로젝트를 할때 checked=”checked” 로 퍼블리싱 되어 오는 경우도 있지만. 같은 팀에서 협업할때 checked 형태를 더 선호하고 convention도 이렇게 되어있어서 나는 개인적으로 checked 하나만 사용하는것을 좋아한다.

그렇다면 input 이 checked 되었을 경우에 css 적으로 효과를 준다면 어떤 선택자를 쓰게될까?
해당 선택자는 다음과 같다.

input:checekd{

}

여기 까지 보자면 뭐가 문제가 있나? 생각 되지만.  문제는 IE8 같은 오래된 브라우저에서 발생한다.

바로 :checked 선택자가 동작하지 않는다. 그렇다면 이 경우 fallback 을 하기 위해서  [checked] 선택자를 사용하는 방법이 있다.

input[checked]{
// 
}

이렇게 되면 IE8 이하의 브라우저에서도 해당 이슈를 해결 할 수 있다.

다만 이런 방법이 또다른 오류를 발생하게 하는데 주로 jQuery로 이 checked 속성을 이용해서 작업할때 발생하게 된다.

예를들어 아래의 코드가 문제가 된다는 것이다.

//[checked] 선택자 안먹음. 
//:checked는동작
var isChecked; 
// isChecked 는 true 또는 false
// 주로 요소들끼리 이벤트가 연결되어있는 경우 사용  
if ( isChecked ){
  $( "input" ).prop( "checked", true ); // checked 적용 
} else {
  $( "input" ).prop( "checked", false ); // checked 해제 
};

 

보통 jQuery로 DOM 조작을 하는경우 2가지 method 를 많이 쓰게 되는데 이 2개의 메소드는$().prop()$().attr() 이다. ( + $().removeAttr() 도 )

prop과 attr 가 혼용되기도 하고 실제로 많은 개발자들이 헷갈려 하기도 한다.

부연 설명을 하자면.  jQuery 1.6 이하의 버전에서는 attr 로 이 prop의 역할도 일부 수행하고 있었기 때문에 주로 개발자들이 헷갈려했고 이 이슈는 1.6 이후의 버전부터 해당 역할이 분리되었으며 jQuery 공식 사이트에서도 해당 이슈에 대해 설명하고 있다. http://api.jquery.com/prop/

그렇기 때문에 대부분 jQuery를 자주 쓰는 개발자 또는 prop과 attr 의 차이를 잘 아는 사람일수록 attr 보다 input 의 checked property를 제어할때는 prop을 사용한다.  다시 말하면 checked 와 같은  property를 조작 하려면 prop 메소드를 쓰는게 맞다. ( js 로 dom의 checked 효과를 제어 하려면. )

 

다만 위의 [checked]와 같이 IE8 대응 코드가 들어가게 된다면 prop 메소드는 제대로 된 checked 효과를 주지 못한다.

그렇기 때문에 이 경우에는 attr() 메소드를 사용해야 하고 attr( “checked”, “checked” ) 메소드를 사용했기 때문에 해당 효과를 제거 하고 싶다면 removeAttr( “checked” )를 사용해야 한다.

즉 위 코드는 아래와 같이 수정되어야 한다.

//[checked] 선택자 안먹음. 
//:checked는동작
var isChecked; 
// isChecked 는 true 또는 false
// 주로 요소들끼리 이벤트가 연결되어있는 경우 사용  
if ( isChecked ){
  $( "input" ).attr( "checked", "checked" ); // checked 적용 
} else {
  $( "input" ).removeAttr( "checked" ); // checked 해제 
};

정리하자면 2가지가 핵심이다.

1. input 의 propery를 컨트롤 하려면 prop() 메소드가 맞다. (jQuery 기준)
2. 단 해당 input 요소가 checked 되었을때 특정 효과를 주는 스타일링이 있다면 (css) 
그리고 해당 서비스가 IE8 이라면!  호환성을 위해 [checked]선택자와 removeAttr() , attr() 을 사용하자 

물론  IE8 때문에 매번 prop대신 attr을 사용하기 싫다면 prop으로 기본 처리를 하고 IE 8이하인 경우에만 removeAttr(), attr() 로 fallback 하게 짜도 된다.

( 선택자는 [checked] ,:checked 둘다 사용해서 css 를 사용해야 한다. IE8 이하만 따로 CSS 를 만들어 관리하는 방법도 있다. )