본문 바로가기

소프트웨어 이야기/장고와 루비온레일즈

[ROR]Asset Pipeline / 자바스크립트, CSS 압축

rails 설치 시, node.js를 설치해야하는 이유에 대해서 찾다보니 assets pipeline 키워드가 등장했다.

레일즈를 production 환경으로 서버를 띄우면, javascript 파일과 css가 압축된 형태로 배포된다. 그래서 그러려니.. 했었는데 그게 바로 assets pipeline에 속하는 기능이였다.


이번 포스팅은 rails guide Asset Pipeline를 번역하는 것을 기반으로 작성해나가던 중... 

rorlab에서 작성한 번역본을 발견하여 핑거프린트의 주의점까지만 작성하고, 블로그 작성을 끝내기로 결정!하였다.




asset pipeline은 JavaScript와 CSS 파일들을 압축하는 기능을 갖고 있다. 그리고 assets 안에 다른 언어들과 커피스크립트, Sass, ERB 같은 pre-processor를 쓸 수 있는 기능을 추가해준다..(?)

asset pipeline은 레일즈 4 버전 대부터는 더이상 핵심 기능이 아니며, sprockets-rails gem으로 프레임워크를 빼내져있다. asset pipeline은 디폴트로 사용되게 되어있는 데 레일즈 프로젝트를 만들 때 --skip-sprockets 를 옵션으로 달면, 제외된다. 

rails new appname --skip-sprockets

레일즈 4에서는 자동적으로 sass-rails, coffee-rails, uglifier gems가 gemfile에 추가되는데, 이 것들은 asset 압축을 위해 Sprockets에 의해 사용되는 gem들이다. 

gem 'sass-rails'
gem 'uglifier'
gem 'coffee-rails'

Rails 4 버전대에서 --skip-sprockets 옵션을 사용하면 Gemfile에 sass-rails와 uglifierto gem이 추가되지 않는다.  그리고 후에 asset pipeline을 사용하고 싶어지면, gemfile에 이 젬들을 추가하면된다. 그리고 --skip-sprockets 옵션이 크게 뭘 바꿔주는건 아니다. 그냥 단지 config/application.rb 파일에 sprockets/railtie를 require하는걸 주석처리 해주는거다. 그래서 나중에 sprockets를 쓰고 싶으면 얘 주석을 풀어주면 된다.

# require "sprockets/railtie"

asset 압축 메서드를 설정하려면, 아래처럼 production.rb 파일에 옵션을 추가해주면 된다. 보통 config.assets.css_compressor 옵션 설정이 안되어있고, 젬파일에 sass-rails gem이 설정되어있으면 자동으로 sass-rails가 CSS 압축에 사용된다.

config.assets.css_compressor = :yui
config.assets.js_compressor = :uglifier


1.1 주요 특징

파이프라인의 첫번째 특징은 Assets를 합쳐주는 기능이다. 이 기능은 브라우저가 웹페이지를 렌더링할 때, request의 수를 줄여주는 역할을 한다. 웹 브라우저는 병열적으로 만들 수 있는 request의 수가 제한적이다. 그래서 이 기능은 적은 request로 어플리케이션의 로딩을 좀더 빠르게 해준다.

Sprocket은 모든 자바스크립트와 css를 각각 하나의 마스터 .js 파일과 .css 파일로 만들어낸다.(하나로 합치는게 아니라 그룹별로 나눠서 묶을 수 도 있다고 함!) 레일즈는 웹브로우저가 파일을 캐싱하도록 하기 위해서, 각 파일명에 MD5 핑거프린트를 넣는다. 그러면 개발자가 파일 컨텐츠를 변경할 때마다 핑거프린트 값이 변경되어, 지난 asset 캐시를 무효화시킬 수 잇다. 

그리고 asset pipeline의 두번째 특징은 asset을 압축해주어, 최소 크기로 만들어준다는 점이다. CSS 파일에서는 공백과 코멘트(주석)을 제거해준다. 그리고 자바스크립트의 프로세스를 더 복잡하게 만들어준다. 즉, 남들이 자바스크립트 로직을 보기 어렵게 압축해버린다는 뜻인거 같다. (자바스크립트 라이브러리들의 .min.js 버전처럼 만들어준다는 의미로 이해했다.)

세번째 특징은 고급언어로 assets을 구현할 수 있도록 해준다. 실제 assets(JavaScript/CSS 파일)으로 만들기 전에, 프리컴파일해주는 기능을 담당한다. 즉 자바스크립트 작성할 때 커피스크립트를 쓰는거, CSS를 작성할 때 Sass를 쓰는거, 그리고 ERB를 쓸 때 말이다!!!!!!!!! (긍까..! ERB파일에는 Ruby 같은 고급언어들을 마구 쓰는데, 얘네를 진짜 html로 변환해주는 역할을 Asset Pipeline이 담당한다는거군! )


1.2 핑거프린트의 주의점

Fingerprinting은 파일의 컨텐츠에 의존적인 형태로 이름을 만든다. 컨텐츠를 변경하면 파일명도 같이 바뀐다. 아예 고정적이거나, 드물게 변경되는 컨텐츠를 위해서 핑거프린트는 파일의 두 버전이 똑같은지 아닌지 알려주는 쉬운 방법을 제공한다.

파일명이 유니크하고, 컨텐츠를 기반으로 할 때, HTTP header는 컨텐츠의 복사본을 유지하려고 어디에나 캐싱을 할 수 있도록 조장한다. ( CDN이던, ISP이던, 네트워크 장비던 웹브라우저이던!) 그래서 컨텐츠가 업데이트 될 때, 핑거프린트도 바뀐다. 이에 따라서 원격 클라이언트는 새 컨텐츠를 서버에 요청할 수 있다. 이 방법을 일반적으로 캐시 파기(cache busting)이라고 부른다.