Web Tech/Gulp

Gulp 사용법 #4 (gulp-sass, gulp-sourcemaps)

jaiyah 2016. 8. 4. 07:00

gulp-sass, gulp-sourcemaps

지난 포스팅에서부터 단계별(#1,2,3)로 전반적인 Gulp 설치와 사용방법에 대해 알아보았습니다.

이 글에서는 CSS 의 전처리기인 Sass 를 컴파일하는 gulp-sass 와 Sass 파일을 역추적할 수 있는 gulp-sourcemaps 에 대해 간단히 알아봅니다.





gulpfile.js

지난 gulp 사용법 #3 의 소스코드를 가지고 이어서 gulp-sass, gulp-sourcemaps 모듈을 설치하고 gulpfile.js 를 작성해 보도록 합니다.


 먼저 두 개의 gulp 플러그인을 다음과 같이 설치하도록 합니다.

Command Line Interface
$ npm i gulp-sass gulp-sourcemaps --save--dev


gulpfile.js 는 다음과 같이 작성할 수 있습니다.

gulpfile
var gulp = require('gulp');

// gulp 플러그인 호출
var concat      = require('gulp-concat'),
    uglify      = require('gulp-uglify'),
    rename      = require('gulp-rename'),
    sourcemaps  = require('gulp-sourcemaps'), // sourcemaps 호출
    scss        = require('gulp-sass'); // sass 호출

/**
 * ==============================+
 * 경로들을 담을 객체 생성
 * ==============================+
 */
var src  = 'project/src';
var dist = 'project/dist';
var paths = {
    js : src + '/js/**/*.js',
    scss : src + '/sass/**/*.scss'
};

/**
 * =====================================+
 * @task : Script 병합,압축,min 파일 생성
 * =====================================+
 */
gulp.task('js:combine', function () {
    return gulp.src(paths.js)
        .pipe(concat('combined.js'))
        .pipe(gulp.dest(dist+'/js'))
        .pipe(uglify())
        .pipe(rename('combined.min.js'))
        .pipe(gulp.dest(dist+'/js'))
});

/**
 * ==============================+
 * @SCSS : SCSS Config(환경설정)
 * ==============================+
 */
var scssOptions = {
    /**
     * outputStyle (Type : String  , Default : nested)
     * CSS의 컴파일 결과 코드스타일 지정
     * Values : nested, expanded, compact, compressed
     */
    outputStyle : "expanded",

    /**
     * indentType (>= v3.0.0 , Type : String , Default : space)
     * 컴파일 된 CSS의 "들여쓰기" 의 타입
     * Values : space , tab
     */
    indentType : "tab",

    /**
     * indentWidth (>= v3.0.0, Type : Integer , Default : 2)
     * 컴파일 된 CSS의 "들여쓰기" 의 갯수
     */
    indentWidth : 1, // outputStyle 이 nested, expanded 인 경우에 사용

    /**
     * precision (Type :  Integer , Default : 5)
     * 컴파일 된 CSS 의 소수점 자리수.
     */
    precision: 6,

    /**
     * sourceComments (Type : Boolean , Default : false)
     * 컴파일 된 CSS 에 원본소스의 위치와 줄수 주석표시.
     */
    sourceComments: true
};

/**
 * ==================================+
 * @task : SCSS Compile & sourcemaps
 * ==================================+
 */

gulp.task('scss:compile', function () {
    return gulp
        // SCSS 파일을 읽어온다.
        .src(paths.scss)
        
        // 소스맵 초기화(소스맵을 생성)
        .pipe(sourcemaps.init())
        
        // SCSS 함수에 옵션갑을 설정, SCSS 작성시 watch 가 멈추지 않도록 logError 를 설정
        .pipe(scss(scssOptions).on('error', scss.logError))

        // 위에서 생성한 소스맵을 사용한다.
        .pipe(sourcemaps.write())
        
        // 목적지(destination)을 설정
        .pipe(gulp.dest(dist + '/css'))
});
 

gulp.task('watch', function () {

    gulp.watch(paths.js, ['js:combine']);
    gulp.watch(paths.scss, ['scss:compile']);

});

// gulp 를 실행하면 default 로 js:combine task, scss:compile task 그리고 watch task 를 실행하도록 한다.
gulp.task('default', ['js:combine','scss:compile','watch']);


gulp 사용법 #3 에서 다룬 소스를 가지고 gulp-sass 와 gulp-sourcemaps 을 추가한 전체 소스파일입니다.

기존 소스외에 변경된 코드부분을 발췌하여 차근차근 진행하도록 하겠습니다.


gulpfile
var concat      = require('gulp-concat'),
    uglify      = require('gulp-uglify'),
    rename      = require('gulp-rename'),
    sourcemaps  = require('gulp-sourcemaps'), // sourcemaps 호출
    scss        = require('gulp-sass'); // sass 호출


패키지 모듈을 위와 같이 gulp-sourcemaps 와 gulp-sass 를 호출하여 참조하고 있습니다.



반복적으로 사용될 경로(path)를 객체리터럴로 생성

gulpfile
/**
 * ==============================+
 * 경로들을 담을 객체 생성
 * ==============================+
 */
var src  = 'project/src';
var dist = 'project/dist';
var paths = {
    js : src + '/js/**/*.js',
    scss : src + '/sass/**/*.scss'
};

gulpfile.js 를 작성하다보면 src(), dest() 등에 반복적인 디렉터리 경로를 자주 사용하게 되는 경우가 발생합니다.

이를 보다 수월하게 한 곳에서 관리하기 위해 객체 리터럴({...})로 디렉터리 경로를 참조해 둔 것입니다.


필자의 디렉터리 구조는 다음과 같이 구성되어 있습니다.



Task sass & sourcemaps 정의하기

gulpfile
/**
 * ==================================+
 * @task : SCSS Compile & sourcemaps
 * ==================================+
 */

gulp.task('scss:compile', function () {
    return gulp
        // SCSS 파일을 읽어온다.
        .src(paths.scss)
        
        // 소스맵 초기화(소스맵을 생성)
        .pipe(sourcemaps.init())
        
        // SCSS 함수에 옵션갑을 설정, SCSS 작성시 watch 가 멈추지 않도록 logError 를 설정
        .pipe(scss(scssOptions).on('error', scss.logError))

        // 위에서 생성한 소스맵을 사용한다.
        .pipe(sourcemaps.write())
        
        // 목적지(destination)을 설정
        .pipe(gulp.dest(dist + '/css'))
});


위 전체 소스중 SCSS Config(환경 설정)에 대한 부분은 위의 task 를 다룬 후 뒤에서 소개하도록 하겠습니다.

지금까지 해왔듯이 task 네이밍을 정의한 후 src() 에 위에서 정의한 객체리터럴에 참조한 경로를 작성하도록 합니다.

그리고 소스맵을 생성하기 위해 pipe 를 연결한 후 내부에 init() 을 호출합니다.

계속 pipe 를 연결하여 참조한 SCSS 를 호출하여 SCSS를 컴파일할 수 있도록 정의합니다. 

전달인자로 scssOptions 를 전달하고 있으며 scssOptions 도 객체를 생성하여 옵션 값들을 참조한 형태로 전달하고 있습니다.

그리고 on() 메서드에서 CLI 에서 SCSS 문법을 작성시 발생할 수 있는 문법 에러를 잡아줄 수 있도록 작성하였습니다.

이 on() 메서드에 에러를 작성하지 않을 시에 watch(지속적인 관찰)를 하더라도 SCSS 문법에 오류가 발생하면 watch 가 중지되므로 작성하는 것을 권장합니다.

다음으로 SCSS 가 컴파일되고 난 후에 소스맵을 사용하기 위해 write() 를 호출하고 컴파일된 CSS 파일을 목적지(dest)에 생성하기 위해 경로를 지정합니다.



소스맵(sourcemaps)은 쉽게 말해 코드상의 위치를 알려주는 것을 말합니다.

예를 들어 SCSS를 사용한다고 가정한다면 컴파일된 CSS 로 HTML과 link 를 시키게 됩니다. 

이 경우에 크롬 개발자도구와 같은 것을 이용하여 CSS 의 값을 확인하거나 디버깅할 시 이슈가 있는 CSS 의 위치를 알 수 있겠지만 원본은 SCSS 이기 때문에 CSS의 위치를 알더라도 SCSS 를 수정해야 하는 입장에서 CSS 위치는 불필요합니다.

이러한 경우 sourcemaps 를 설정하게 되면 SCSS 파일의 위치를 알려주기 때문에 유용하게 사용할 수 있습니다.

그리고 유명한 라이브러리들은 거의 소스맵을 가지고 있으며 대표적으로 jQuery 또한 소스맵 설정이 되어있습니다.



아래 그림처럼 크롬 개발자도구의 Settings 에서 자바스크립트와 CSS 의 소스맵 체크여부를 확인하신 후 소스맵을 사용하시기 바랍니다.



SCSS Options 값 정의

이 글에서는 유용하게 쓰일 만한 옵션 값만 정리하였으며 주석으로 상세한 설명을 해 놓았으므로 주의할 점만 언급하도록 하겠습니다.

gulpfile
/**
 * ==============================+
 * @SCSS : SCSS Config(환경설정)
 * ==============================+
 */
var scssOptions = {
    /**
     * outputStyle (Type : String  , Default : nested)
     * CSS의 컴파일 결과 코드스타일 지정
     * Values : nested, expanded, compact, compressed
     */
    outputStyle : "expanded",

    /**
     * indentType (>= v3.0.0 , Type : String , Default : space)
     * 컴파일 된 CSS의 "들여쓰기" 의 타입
     * Values : space , tab
     */
    indentType : "tab",

    /**
     * indentWidth (>= v3.0.0, Type : Integer , Default : 2)
     * 컴파일 된 CSS의 "들여쓰기" 의 갯수
     */
    indentWidth : 1, // outputStyle 이 nested, expanded 인 경우에 사용

    /**
     * precision (Type :  Integer , Default : 5)
     * 컴파일 된 CSS 의 소수점 자리수.
     */
    precision: 6,

    /**
     * sourceComments (Type : Boolean , Default : false)
     * 컴파일 된 CSS 에 원본소스의 위치와 줄수 주석표시.
     */
    sourceComments: true
};

위 옵션 값중에 indentType 에 따라서 indentWidth 가 달라집니다. 만약 space 값으로 설정하고 indentWidth 4라면 공백(....) 4칸이 정의되고 타입이 tab이라면 탭을 4번 사용한 것과 같습니다.

그리고 sourceComments는 컴파일된 CSS 에 SCSS 파일의 위치를 알려주는 주석이 달려있게 됩니다.

sourceMaps 를 사용한다면 굳이 sourceComments를 사용할 필요는 없을 것입니다.


Sass 의 자세한 옵션은 node-sass 를 참고 그리고 sourcemaps 옵션은 gulp-sourcemaps 에서 확인바랍니다.



watch SCSS

지금까지 path 설정과 sass 옵션값을 정의하고 task 등록을 완료하였습니다.

task 등록을 마쳤으므로 지속적인 업무 관찰을 할 수 있도록 watch 에 scss 를 아래와 같이 작성하도록 합니다.

gulpfile
gulp.task('watch', function () {

    gulp.watch(paths.js, ['js:combine']);
    gulp.watch(paths.scss, ['scss:compile']);

});

위와 같이 watch() 메소드에 경로를 지정하고 scss task 를 지정한 이름을 작성하도록 합니다.



gulp default task 정의하기

gulpfile
/**
 * =========================================================================+
 * default 로 CLI에서 gulp 를 실행하면
 * js:combine task, scss:compile task 그리고 watch task 를 실행되도록 정의한다.
 * =========================================================================+
 */
gulp.task('default', ['js:combine','scss:compile','watch']);


CLI 에서 다음과 같이 :

Command Line Interface
$ gulp

default 명령어인 gulp 를 실행하면 'js:combine','scss:compile' task 를 실행하고 watch task를 실행하게 될 것입니다.



지금까지 gulp-sass & gulp-sourcemaps 을 간단히 다뤄보았습니다.

다음에는 좀 더 유용한 플러그인을 추가하여 사용해 볼 수 있는 시간을 가져보도록 하겠습니다.





Jaehee's WebClub