Gulp

설정 및 설치

  • package.json 생성
{
  "name": "test-front-web",
  "version": "0.0.1.SNAPSHOT",
  "devDependencies": {

  }
}
  • gulp 설치
$ npm install --save-dev gulp 

위의 명령을 실행하고 나면 package.json 파일에 다음과 같이 "gulp": "^3.9.1" 가 추가된 것을 확인할 수 있다.

{
  "name": "test-front-web",
  "version": "0.0.1.SNAPSHOT",
  "devDependencies": {
    "gulp": "^3.9.1"
  }
}

거기에 node_modules 디렉터리가 추가되고 다양한 의존성 라이브러리가 추가되었다.

프로젝트 폴더에 gulpfile.js 를 생성한다. 그리고 그 안에,

// Include gulp
var gulp = require('gulp');

코드를 추가한다.

추가할 수 있는 태스크의 종류는 많지만 그 중에서 몇가지만 소개한다:

  • gulp.task(name, function) - 이름으로 함수를 등록
  • gulp.watch(global, function) - 전역변수의 변경사항이 생겼을 때 호출할 함수 정의
  • gulp.src(global) - 읽어올 위치
  • gulp.dest(folder) - 작성된 파일을 놓을 위치

gulp와 파일 연결하기(Concatenating)

gulp만 설치한다고 끝나는 것은 아니다. gulp 가 동작할 수 있도록 플러그인을 설치하고 gulpfile 에 태스크를 추가해야 한다. gulp-concat 플러그인이 필요하다.

$ npm install --save-dev gulp-concat 

를 실행하고 나면 package.json 에 "gulp-concat": "^2.6.0" 가 추가된다.

이제 gulpfile 에 필요한 테스크를 추가한다.

// Include gulp
var gulp = require('gulp');

// Include plugins
var concat = require('gulp-concat');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function() {
   return gulp.src('src/js/*.js')
       .pipe(concat('honeymon.js'))
       .pipe(gulp.dest('build/js'));
});

// Default Task
gulp.task('default', ['scripts']);

gulp-concat 플러그인 설정을 포함하고 gulp.task 를 사용하여 기본 테스크에 script 를 추가했다. 이 태스크는 3단계 과정으로 처리가 된다:

  1. gulp.src 에서 정의한 src/js 디렉토리에 있는 확장자 js 를 연결한다.
  2. main.js 로 연결한다.
  3. build/js 디렉토리에 main.js 파일을 밀어 넣는다.

gulp 를 이용한 JS 최소화하기

보통 자바스크립트를 배포할 때 최소화(Minify)하는 과정을 거치는데 gulp 에서는 이를 처리하는 플러그인이 있다. 그리고 나서 파일명 접미사로 .min 를 붙이는 rename 플러그인도 함께 설치한다.

$ npm install --save-dev gulp-unglify gulp-renmae 

이제 gulpfile.js 에 scripts 태스크를 수정한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('js'));
});

gulp 를 이용한 css 처리

gulp 를 이용해서 sass 파일을 컴파일하여 css 를 생성하는 태스크를 추가한다.

루비의 공식적인 sass 컴파일러를 설치한다.

$ npm install --save-dev gulp-ruby-sass 

이제 gulpfile.js 에 sass 태스크를 수정한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('build/js'));
});

//Compile SASS
gulp.task('sass', function () {
    sass('src/scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'));
    sass('src/scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css/honeymon'));
});

// Default Task
gulp.task('default', ['scripts', 'sass']);

프로젝트에 사용하는 이미지 이동

이제 gulp 에서 많은 시간이 걸리는 작업이 남았다. 스크립트나 스타일시트 작업보다 더 오래 걸릴 것이다. gulp-imagemin 와 gulp-cache 를 이용해서 이미지를 최적화하는 작업을 진행한다.

$ npm install --save-dev gulp-imagemin gulp-cache 

gulp-imagemin 와 gulp-cache 에 대한 의존성을 추가하고 image 태스크를 수정하자.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src('src/js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest('build/js'));
});

//Move image files
gulp.task('images', function() {
    return gulp.src(srcPath + '/img/**/*')
        .pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass('src/scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css'));
    sass('src/scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest('build/css/honeymon'));
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'images', 'sass']);

// Default Task
gulp.task('default', ['build']);

실제로 많이 걸린다..

➜  test-front-web git:(master) ✗ gulp
[14:27:52] Using gulpfile ~/workspace/honeymon/test-front-web/gulpfile.js
[14:27:52] Starting 'scripts'...
[14:27:52] Starting 'images'...
[14:27:52] Starting 'sass'...
[14:27:52] Finished 'sass' after 19 ms
[14:27:52] Finished 'scripts' after 147 ms
[14:27:54] Finished 'images' after 2.18 s
[14:27:54] Starting 'build'...
[14:27:54] Finished 'build' after 1.61 μs
[14:27:54] Starting 'default'...
[14:27:54] Finished 'default' after 1.5 μs

프로젝트에서 작성한 html 을 이동시키자.

html 을 옮기는 과정에서는 2가지 작업을 해야한다.

  • src html 에서 보고 있는 *.css 와 *.js 의 경로를 변경해야 한다.
  • build 로 이동시키면서 빌드 컴파일러된 *.css 와 *.js 를 보도록 변경해야 한다.

우선은 src 에서 build 로 이동처리를 먼저 하자.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');

var buildPath = 'build/'
var srcPath = 'src/'

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src(srcPath + 'js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest(buildPath + 'js'));
});

//Move image files
gulp.task('images', function() {
    gulp.src(srcPath + 'img')
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass(srcPath + 'scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css'));
    sass(srcPath + 'scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css/honeymon'));
});

gulp.task('html-copy', function() {
    gulp.src([srcPath + 'index.html', srcPath + 'sample.html'])
        .pipe(gulp.dest(buildPath))

    gulp.src(srcPath + 'tx/*.html')
        .pipe(gulp.dest(buildPath + '/tx'))
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'images', 'sass', 'html-copy']);

// Default Task
gulp.task('default', ['build']);

이제 gulp-html-replace 플러그인을 설치하고 html 을 옮기면서 stylesheet 와 script 를 처리해보자.

$ npm install --save-dev gulp-html-replace

이제 html-copy 테스크에 추가한다.

gulp.task('html-copy', function () {
    //SEE: https://www.npmjs.com/package/gulp-html-replace
    gulp.src([srcPath + 'sample.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/style.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src([srcPath + 'index.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/index.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src(srcPath + 'tx-*.html')
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/tx.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));
});

src 디렉토리 감시하기

이제 src 디렉토리 내에 있는 파일들의 변경사항이 생겼을 때 이를 감지해서 build 태스크를 실행하도록 만들자.

watch 태스크를 생성한다.

gulp.task('watch', function() {
    // Watch .js files
    gulp.watch(srcPath + 'js/*.js', ['scripts']);
    // Watch .scss files
    gulp.watch(srcPath + 'scss/*.scss', ['sass']);
    // Watch image files
    gulp.watch(srcPath + 'images/**/*', ['images']);
});

그 후 기본 태스크에 watch 태스크를 추가한다.

// Include gulp
var gulp = require('gulp');
// Include plugins
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var sass = require('gulp-ruby-sass');
var imagemin = require('gulp-imagemin');
var cache = require('gulp-cache');
var htmlReplace = require('gulp-html-replace');
var cleanCSS = require('gulp-clean-css');

var buildPath = 'build/'
var srcPath = 'src/'

//Concatenate JS File: src/js 에 있는 파일들을 main.js 로 연결
gulp.task('scripts', function () {
    return gulp.src(srcPath + 'js/*.js')
        .pipe(concat('honeymon.js'))
        .pipe(rename({suffix: '.min'}))
        .pipe(uglify())
        .pipe(gulp.dest(buildPath + 'js'));
});

//MOVE libraries
gulp.task('libraries', function () {
    //Copy Javascript
    gulp.src([
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.min.js',
        'node_modules/bootstrap-select/dist/js/bootstrap-select.min.js'])
        .pipe(gulp.dest(buildPath + 'js/libs'));

    //Copy StyleSheet
    gulp.src([
        'node_modules/bootstrap/dist/css/bootstrap.min.css',
        'node_modules/bootstrap-select/dist/css/bootstrap-select.min.css'])
        .pipe(gulp.dest(buildPath + 'css/libs'));

    //Copy font-awesome
    gulp.src(['./node_modules/font-awesome/css/font-awesome.min.css'])
        .pipe(gulp.dest(buildPath + 'css/libs/font-awesome/css'));
    gulp.src(['./node_modules/font-awesome/fonts/*'])
        .pipe(gulp.dest(buildPath + 'css/libs/font-awesome/fonts'));

    //copy bootstrap
});


//Move image files
gulp.task('images', function () {
    return gulp.src(srcPath + '/img/**/*')
        .pipe(cache(imagemin({optimizationLevel: 5, progressive: true, interlaced: true})))
        .pipe(gulp.dest(buildPath + 'img'));
});

//Compile SASS
gulp.task('sass', function () {
    sass(srcPath + 'scss/style.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css'));
    sass(srcPath + 'scss/honeymon/*.scss', {style: 'compressed'})
        .pipe(rename({suffix: '.min'}))
        .pipe(gulp.dest(buildPath + 'css/honeymon'));
});

//Replace html js, css
gulp.task('html-copy', function () {
    //SEE: https://www.npmjs.com/package/gulp-html-replace
    gulp.src([srcPath + 'sample.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/style.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src([srcPath + 'index.html'])
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/index.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));

    gulp.src(srcPath + 'tx-*.html')
        .pipe(htmlReplace({
            css: [
                'css/libs/bootstrap.min.css',
                'css/libs/font-awesome/css/font-awesome.min.css',
                'css/libs/bootstrap-select.min.css',
                'css/style.min.css',
                'css/honeymon/tx.min.css'
            ],
            js: [
                'js/libs/jquery.min.js',
                'js/libs/bootstrap.min.js',
                'js/libs/bootstrap-select.min.js',
                'js/honeymon.min.js'
            ]
        }))
        .pipe(gulp.dest(buildPath));
});

//Watch project
gulp.task('watch', function () {
    // Watch .js files
    gulp.watch(srcPath + 'js/*.js', ['scripts']);

    // Watch .scss files
    gulp.watch([srcPath + '**/*.scss'], ['sass']);
    // gulp.watch(srcPath + 'scss/honeymon/*.scss', ['sass']);

    // Watch image files
    gulp.watch(srcPath + 'img/**/*', ['images']);

    // Watch .html files
    gulp.watch(srcPath + '*.html', ['html-copy']);
});

//Build JavaScript, Images, Sass
gulp.task('build', ['scripts', 'libraries', 'images', 'sass', 'html-copy']);

// Default Task
gulp.task('default', ['build', 'watch']);

이렇게 테스트가 추가되고 나면 src 내에 작은 변화가 생기면 자동적으로 변환이 진행되며 그 결과를 확인할 수 있게 된다.

gulp 동작 실행

gulp 명령어만 실행하면 다음과 같이 build 태스크에 있는 것들이 실행되고 watch 태스크가 실행되면서 디렉토리의 변경사항을 감시하여 변동사항이 생기면 자동으로 빌드가 진행된다.

/usr/local/bin/node /honeymon/node_modules/gulp/bin/gulp.js --color --gulpfile /honeymon//gulpfile.js default
[10:58:15] Using gulpfile ~/workspace/honeymon/test-front-web/gulpfile.js
[10:58:15] Starting 'scripts'...
[10:58:15] Starting 'libraries'...
[10:58:15] Finished 'libraries' after 7.74 ms
[10:58:15] Starting 'images'...
[10:58:15] Starting 'sass'...
[10:58:15] Finished 'sass' after 33 ms
[10:58:15] Starting 'html-copy'...
[10:58:15] Finished 'html-copy' after 14 ms
[10:58:15] Starting 'watch'...
[10:58:15] Finished 'watch' after 56 ms
[10:58:16] Finished 'scripts' after 272 ms
[10:59:31] Starting 'sass'...
[10:59:31] Finished 'sass' after 6.61 ms
[10:59:32] write ./style.css
[11:00:21] Starting 'sass'...
[11:00:21] Finished 'sass' after 5.03 ms
[11:00:22] write ./style.css

참고문헌


Bower, A package manager for the web
Web sites are made of lots of things — frameworks, libraries, assets, utilities, and rainbows. Bower manages all these things for you.
> 최근의 웹사이트는 다양한 것들(프레임워크, 라이브러리, 자원, 유틸리티 그리고 레인보우(!?))로 만들어진다. Bower는 이 모든 것을 관리한다.

Bower는 찾고자 하는 것들을 각지에서 탐색하고, 다운로드하고, 설치하고 붙인다. Bower는 bower.json 매니페스트 파일을 기준으로 패키지들을 추적관리한다.
어떤 패키지를 사용할지는 사용자에게 달려있다.

Bower는 프론트엔드에 최적화되어 있다. Bower는 간단한 의존성구조, 각 패키지별 대표버전만을 요구하며, 페이지로드를 최소한으로 감소시킨다.

1. Bower 설치

Bower는 커맨드라인 유틸리티다. npm*(https://www.npmjs.com/) 이 설치되어 있어야 한다.

$ npm install -g bower

Bower는 Node 그리고 npm  Git을 필요로 한다.

2. 시작

2.1. 패키지 설치

패키지 설치는 bower install 이용한다. Bower가 설치한 패키지는 bower_components/에 설치된다.

$ bower install <package>

패키지는 github, git 엔드포인트, URL 그리고 기타등등이 가능하다. 보다 자세한 내용은 bower install 을 살펴보기 바란다.

# registered package
$ bower install jquery
# GitHub shorthand
$ bower install desandro/masonry
# Git endpoint
$ bower install git://github.com/user/package.git
# URL
$ bower install http://example.com/script.js

2.2. 패키지 검색

Search Bower pacakge와 선호하는 프로젝트의 등록된 패키지명을 검색한다.

2.3. 패키지 저장

패키지 저장은 bower init 을 통해서 bower.json 에 등록한다.

2.4. 패키지 사용

패키지를 사용하는 것은 사용자가 결정한다. Bower와 함께 Grunt, RequireJS, Yeoman, 그리고 다양한 도구들을 함께 사용하거나,
빌드할때 API를 활용하는 것을 권장한다. 또한 설치된 패키지를, 다음의 jquery사용의 경우처럼, 바로 사용할 수도 있다.

<script src="bower_components/jquery/dist/jquery.min.js"></script>

다음은 RequireJS를 이용하여 각 페이지별 자바스크립트 파일/모듈을 적재해보자.

참고


  1. ... Java 백엔드 개발도 잘 못하는데... 프론트엔드도 깨작거리게 되었다.

+ Recent posts