본문으로 바로가기

Gulp 사용법 #6 (Browser-sync)

category Web Tech/Gulp 2016. 8. 5. 14:58

Gulp with BrowserSync

로컬에서 프론트엔드 작업시 웹서버를 실행하여 작업한 결과물을 확인하게 됩니다. 

파일을 수정할 때마다 띄워놓은 웹서버에서 refresh 를 하여 작업물을 확인하는 것이 일반적이지만 지금 다루려고 하는 BrowserSync 를 사용하면 위의 과정을 보다 편리하게 자동화시킬 수 있습니다.


BrowserSync는 Gulp 플러그인이 아닌 node.js 기반의 어플리케이션이지만 Gulp 와 매끄럽게 연동해서 사용할 수 있습니다. 

자체적으로 다양한 옵션을 가진 미니 웹서버 기능을 지원하고, 파일 변경시에 이를 자동으로 감지해서 브라우저 Refresh 를 수행할 수 있습니다. 

가장 흥미로운 기능은 여러 개의 브라우저를 실행했을 때 한 브라우저에서 클릭을 하면 다른 브라우저에서도 동일한 위치에 클릭 이벤트를 발생시켜 여러 브라우저에서 동시에 동일하게 동작할 수 있도록 도와주는 기능입니다. 

BrowserSync 라는 이름 그대로 브라우저들간에 동작을 Sync 해주고 이외에도 프록시, 미들웨어 등 다양한 기능을 지원하고있기 때문에 다양한 필요에 대응해줄 수 있습니다.




browser-sync

브라우저 싱크를 사용하기 위해서 먼저 npm 을 이용하여 BrowserSync 를 설치해 주어야 합니다. 

앞서 언급한대로 BrowserSync는 Gulp 플러그인이 아닌 Gulp 와 같은 node.js 기반 어플리케이션이기 때문에 BrowserSync만 사용하고 싶다면 -g 옵션으로 설치해도 됩니다. 

하지만 여기에서는 Gulp 와 연동하는 것을 염두에 두고 있기 때문에 --save-dev 옵션으로 설치하도록 합니다.

Command Line Interface
$ npm install browser-sync --save-dev



gulpfile.js

gulpfile.js 코드는 앞서 gulp 사용법 #5 예제들을 종합해서 BrowserSync 와의 연동하는 방법까지 추가해서 다루도록 하겠습니다.

그리고 #5 에 사용했던 livereload 는 browser-sync 로 인해 더이상 필요가 없어졌기 때문에 제거하고 작성하도록 합니다.

gulpfile
// gulp 및 패키지 모듈 호출
var gulp        = require('gulp'),
    concat      = require('gulp-concat'),
    uglify      = require('gulp-uglify'),
    rename      = require('gulp-rename'),
    sourcemaps  = require('gulp-sourcemaps'),
    scss        = require('gulp-sass'),
    browserSync = require('browser-sync').create(); // browser-sync 호출

/**
 * ==============================+
 * @Path 정의
 * ==============================+
 */
var src   = 'project/src';
var dist  = 'project/dist';
var paths = {
    js : src + '/js/**/*.js',
    scss : src + '/sass/**/*.scss'
};

/**
 * =====================================+
 * @task : HTML livereload 반영
 * =====================================+
 */
gulp.task('html', function () {
    return gulp
        .src('./**/*.html')
            
        /**
         * HTML 파일을 browserSync 로 브라우저에 반영
         */
        .pipe(browserSync.reload({
            stream : true
        }));
});

/**
 * =====================================+
 * @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({suffix : ".min"}))
        .pipe(gulp.dest(dist+'/js'))
            
        /**
         * 스크립트 파일을 browserSync 로 브라우저에 반영
         */
        .pipe(browserSync.reload(
            {stream : true}
        ));
});

/**
 * ==============================+
 * @SCSS : SCSS Config(환경설정)
 * ==============================+
 */
var scssOptions = {
    outputStyle : "expanded",
    indentType : "tab",
    indentWidth : 1,
    precision: 3,
    sourceComments: false
};

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

gulp.task('scss:compile', function () {
    return gulp
        .src(paths.scss)
        .pipe(sourcemaps.init())
        .pipe(scss(scssOptions).on('error', scss.logError))
        .pipe(sourcemaps.write())
        .pipe(gulp.dest(dist + '/css'))

        /**
         * SCSS 컴파일을 수행한 후 browserSync 로 브라우저에 반영
         */
        .pipe(browserSync.reload({
            stream : true
        }));
});

/**
 * ==============================+
 * @task : browserSync
 * ==============================+
 */
gulp.task('browserSync', ['html', 'js:combine', 'scss:compile'], function () {
    return browserSync.init({
        port : 3333,
        server: {
            baseDir: './project'
        }
    });
});

/**
 * ==================================+
 * @task : watch 파일 변경을 감지
 * ==================================+
 */
gulp.task('watch', function () {
    
    gulp.watch('./**/*.html', ['html']); 
    gulp.watch(paths.js, ['js:combine']);
    gulp.watch(paths.scss, ['scss:compile']);

});

/**
 * ==============================+
 * @task : gulp default
 * ==============================+
 */
gulp.task('default', ['browserSync','watch']);


BrowserSync 모듈을 호출하는 require('browser-sync').create(); 라인을 살펴봅니다. 

BrowserSync는 Create 메서드로 생성을 먼저 해주어야 하기 때문에 바로 create 메서드를 호출하는 것이 일반적입니다.


그리고 코드상에서 browserSync 라는 task 가 추가되었는데, 이 task를 자세히 살펴보면 먼저 각각 JavaScript, CSS, HTML 파일의 빌드 task 들을 먼저 수행한 뒤 dist 폴더를 기준으로 BrowserSync 의 웹서버 옵션을 활성화해서 초기화하는 것을 볼 수 있을 것입니다. 

BrowerSync 는 다양한 옵션들을 지원하고 있는데 지원되는 옵션은 BrowserSync Docs 를 참고하시기 바랍니다.


또한 각 task 들에서 이전과 달리 BrowserSync의 reload 메서드를 호출하는 .pipe(browserSync.reload({stream:true})); 코드가 추가된 것을 확인하실 수 있습니다.

gulp.dest() 메서드로 dist 디렉터리에 빌드된 결과물을 저장한 뒤에, pipe 를 계속 연결하여 BrowserSync의 reload 메서드를 호출하면, 자동으로 브라우저에 새로 빌드된 결과물이 반영되도록 브라우저가 Refresh 되어 더이상 브라우저의 Refresh 버튼을 눌러 줄 필요가 없어지게 됩니다. 

reload 메서드의 옵션으로 stream: true 를 주었기 때문에 변경된 파일만 stream 으로 브라우저에 전송되어 Refresh 없이도 반영이 되게 됩니다.





Jaehee's WebClub