웹을 떠받치는 기술은 모두 비슷한 사정이지만, 특히나 CSS 작성 결과물은 개개인의 코딩 습관과 숙련도 그리고 유동적인 브라우저 지원 상황에다 반갑지 않은 버그 등 여러 외적 요인이 모여서 큰 변수로 작용하기 마련이다. 표면적으론 단순해 보이지만, 자유의지에 맡겨진 properties 지정 작업은 픽셀 하나하나 차곡차곡 쌓아 올린 작용과 반작용의 만남이다. 이것은 잔잔한 브라우저 창에 파도의 물결을 일으키는 상상력의 실현이 될 수도, 혹은 의도치 않은 부작용 때문에 엉키고 뒤틀려버린 혼란의 골칫거리가 되버릴 수도 있다. 그래서 항상 집중과 주의가 요구되는 고난의도 작업.

이런 복잡 미묘한 상황에 조금이라도 외적 잡음을 줄이고 동시에 CSS 작성의 효율을 높이고자 OOCSS, SMACSS, BEM과 같은 여러 구조적 방법론들이 계속 등장하고 있으며, 또한 공동 작업의 편의를 위한 CSS 코딩 스타일 통합을 목적으로 properties 지정 순서에서부터 공백의 개수, 따옴표 스타일 등 아주 세세하고 민감한 부분까지 일관되게 정리해주는 CSS 빗질 도구까지 마련되어 있다.

여기서 한발 더 나아가 SASS, Less와 같은 일명 Pre-Processor의 힘을 빌려 CSS 작성 효율을 구조적으로 좀 더 끌어올리려는 노력도 활발한데, 최근엔 한술 더 떠서 CSS 후처리 과정까지 더해준 Post-Processor들도 덩달아 비 온 뒤 잡풀처럼 여기저기 생겨나고 있어서 이들의 태생 목적과 사용법을 소개하고자 한다.

CSS Pre-Processors vs. Post-Processors

CSS Pre-Processor는 기존 CSS 문법의 확장 성격으로 자기만의 syntax로 작성하고 parse/compile 과정을 거쳐 일반 CSS로 되돌려준다. 이에 반해 Post-Processor는 그냥 맨살의 CSS 문법으로 작성된 것을 해석/처리해서 다시 일반 CSS를 돌려주는 차이가 있다.

정의만 살펴보면, Post-Processor를 써서 얻을 수 있는 장점을 이해하기 힘든데, Post-Processor가 제공하고 있는 기능 중 가장 많이 애용되는 Autoprefixer의 사용 예를 보면 Post-Processor만의 장점이 뚜렷해진다.

CSS3 규칙 중 브라우저 지원 때문에 prefix를 일일이 붙여줘야 하는 상황이라면, Sass(SCSS)의 경우 mixin 기능으로 다음과 같이 적용해 줄 수 있다.

@mixin flexbox() {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}
 
.box {
  @include flexbox();
}

하지만 Autoprefixer의 힘을 빌리면 CSS 작성은 아주 단순해진다.

.box { display: flex; }

원래의 CSS 문법을 그대로 작성하면, 후처리 과정을 거쳐 골치 아픈 vender prefix를 더해 다음과 같이 돌려준다.

.box {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
}

특정 CSS property의 브라우저 지원 상황을 일일이 확인해 가면서 mixin을 써야 할지 말아야 할지 고민할 필요가 없는 것이다.
Post-Processor(PostCSS) 소개 슬라이드: PostCSS: the Future after Sass and Less

Post-Processor를 이용한 깔끔하고 미래 지향적인 CSS 작성(이)란 제목의 글 마저 읽기 →

이 글은 Modules, a Future Approach to JavaScript Libraries – Tuts+ Code Article의 글을 한국어로 옮긴 것입니다. (참고로, 지금까지 이곳에 올린 글 중에 가장 긴 게 아닌가 생각되네요.)

jQuery와 같은 JavaScript 라이브러리는 거의 지난 10여 년 동안 웹 브라우저에서 실행될 JavaScript를 작정할 때마다 당연히 가장 먼저 추가해야만 되는 것으로 여겨지고 있습니다. 이러한 현상은 각종 브라우저 간 차이와 구현 문제로 어쩔 수 없었으며, 그래서 지금까지 그 임무를 훌륭히 수행하고 있습니다. jQuery는 이러한 브라우저 버그와 각자 기괴하게 꼬인 것들을 알아서 말끔하게 덮어주면서 가령 이벤트 처리나 Ajax 그리고 DOM 조작과 같은 작업을 손쉽게 만들어 주었습니다.

이땐, jQuery가 거의 모든 문제를 해결해 주었기에, 자연스레 추가해서 얻은 막강한 힘을 빌려 그냥 작업에만 바로 집중할 수 있었지요. 이것은 마치 브라우저가 제대로 작동하려면 있어야 하는 블랙박스와 같았습니다.

하지만 지금, 웹은 진보하였고, API도 많이 개선되었으며 마찬가지로 웹 표준도 그만큼 더 많이 구현되기 시작하면서 아주 빠르게 변화하는 환경이 되었습니다. 그래서 과연 미래의 브라우저에도 이런 거대한 라이브러리들이 필요로 할지 의문을 가질 수밖에 없게 되었습니다. 결국 모듈(Module)에 적합한 환경으로 변화하고 있는 것입니다.

모듈 소개

모듈은 어떤 하나의 특화된 기능을 아주 잘 수행하는 어떤 독립된 집합체라 할 수 있습니다. 예를 들어, 모듈은 어떤 특정 엘르먼트에 클래스를 추가하는 기능을 수행하거나, 혹은 Ajax를 이용한 HTTP 통신을 하는 등 그 가능성은 무한합니다.

모듈은 그 모양과 크기가 여러 가지 있는데, 일반적인 목적은 하나같이 작업 환경에 불러오기만 하면 알아서 원래 가지고 있는 기능을 잘 수행하는 데 있습니다. 보통 모듈은 기본적으로 각각의 개발자 문서와 설치 과정 그리고 브라우저나 서버와 같은 실행 환경의 정보를 제공하고 있습니다.

이러한 모듈은 프로젝트에 필요한 기능을 메꿔주면서 나중에 추가와 제거와 같은 의존성 관리가 훨씬 간편해지는 효과가 있습니다. 모듈이 제공하는 장점과 유연성을 생각해보면, 이젠 어떤 덩치 큰 라이브러리를 단순하게 추가하는 일은 점점 줄어들 것입니다. 다행스럽게도 jQuery와 같은 라이브러리들도 이점을 인식해서 필요한 기능만 내려받을 수 있는 온라인 도구를 제공하기 시작했습니다.

최근에 소개된 API들은 모듈로 작성될 수도 있는 영감을 북돋게 하는 커다란 촉진제 역할을 하였고, 이젠 브라우저의 구현 상황도 상당히 좋아져서, 대부분의 일상적 작업은 작은 기능의 모듈을 작성해서 대신 처리해 줄 수도 있게 되었습니다.

모듈의 시대는 이미 도래했으며, 앞으로도 오랫동안 그 소임을 계속 맡아주리라 기대되고 있습니다.
Modules, 앞으로 JavaScript 라이브러리가 나아갈 길(이)란 제목의 글 마저 읽기 →

node module을 처음 접해서 사용하다 보면 많은 사람이 갖게 되는 질문인데, 다음 글에 간단명료하게 정의되어 있다.

Difference between “module.exports” and “exports” in the CommonJs Module System – Stack Overflow

결국, 다음 코드로 간단히 설명된다.

var module = { exports: {} };
var exports = module.exports;
 
// your code 
 
return module.exports;

exports의 property에 설정된 것은 문제없지만, exports 자체를 다른 것으로 설정해서 바꿔버리면 module.exports와의 연결고리가 끊어지게 되므로 이점 주의해야 한다.

좀 더 자세히 설명해놓은 글: Node.js Module – exports vs module.exports

module.exports.*exports.* 모두 다 함께 쓸 수 있다고 해서 번갈아 혼합해서 쓸 필요는 없고, module.exports.*의 존재 자체는 이해하되 일관성 있게 exports.*를 애용해서 사용해 줄 것을 권장한다.

꼬리표:
Function.prototype.throttle = function(n) {
  var fn = this;
  var throttled = false;
  return function() {
    if (throttled) return;
    throttled = true;
    fn.apply(null, arguments);
    setTimeout(function() {
      throttled = false;
    }, n);
  };
};

가령 window.onscroll event에 심어놓은 function이 불필요하게 너무 자주 실행되는 것을 방지하려는 목적으로 사용될 수 있는데, 간단한 사용법으로 다음과 같이 적용할 수 있다.

var logTest = function() {
  console.log('test');
};
 
window.onscroll = logTest.throttle(1000);

이렇게 해놓으면, 최대 1초에 한 번씩만 등록된 함수가 실행되면서 콘솔에 해당 메시지가 찍히는 것을 볼 수 있다. 비슷한 함수로 Underscore.jsLo-Dash에서도 모두 throttle이란 이름의 함수를 함께 제공하고 있음.

따온 곳: Functional Javascript Tools & Tricks – Tim Ruffles on Vimeo

가끔 웹페이지에 걸려있는 링크를 타고 들어가 보면 타이머를 걸어 놓고서 일정 시간이 지난 후에야, 가령 특정 form의 자료 입력과 같은, 작업을 진행할 수 있게 해 놓은 곳과 마주치곤 한다. 보통 링크 클릭을 통한 광고와 수익의 창출을 목적으로 이런 현상이 퍼지는데, 이럴 때마다 불편함과 함께 은근 짜증을 일으키게 한다.

그래서 이런 때를 대비해서 아래와 같은 JavaScript timers의 지연 시간을 아주 짧게 써는 실험 목적의 주문을 만들어 봤다. 주문이 잘 먹히면 더딤 없는 쾌속 진행의 길을 뚫을 수 있다. (물론, 사이트에서 어떤 추가 확인장치를 해 놓은 곳이라면 이것도 별 소용이 없겠지만.)

var originalInterval = this.setInterval, originalTimeout = this.setTimeout;
this.setInterval = function(funcdelay) {
  originalInterval(func, 10);
};
this.setTimeout = function(funcdelay) {
  originalTimeout(func, 10);
};

이를 이용한 간편 사용 목적의 bookmarklet: fastTimer – 가속기가 달린 고장난(?) Timer.

꼬리표: