Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

gulp에서 Babel을 사용한 ES2015 코드 변환

얼마 전에 Babel로 ECMAScript 2015 사용하기라는 글을 올렸는데 ES2015를 사용하기 위한 간단한 Babel 설정을 살펴봤다. 실제 프로젝트에서 Babel로 ES2015로 작성한 코드를 계속해서 트랜스파일 하려면 자동화된 환경이 필요하다. 여기서는 gulp를 사용한다.

ES2015 설정

// src/lib.js
let sum = (a, b) => a + b;

console.log(sum(3, 4));

src/lib.js에 위와 같은 간단한 ES2015 코드가 있다고 해보자. 이를 Babel로 트랜스파일 하려면 npm install --save-dev babel-preset-es2015로 패키지를 설치하고 .babelrc에 다음과 같은 프리셋을 설정한다.

{
  "presets": ["es2015"]
}


gulp 설정

npm install --save-dev gulp gulp-babelgulp-babel을 설치하고 gulpfile.js에 다음과 같은 테스크를 만든다.

// gulpfile.js
var gulp = require('gulp');
var babel = require('gulp-babel');

gulp.task('babel', function() {
  return gulp.src('src/**/*.js')
    .pipe(babel())
    .pipe(gulp.dest('out'));
});

간단히 설명하면 src 폴더 내의 모든 .js파일을 babel로 변환한 뒤 out 폴더에 변환 코드가 생기게 된다.

$ gulp babel
[02:53:21] Using gulpfile ~/exmaple/gulpfile.js
[02:53:21] Starting 'babel'...
[02:53:23] Finished 'babel' after 2.06 s

gulp babel을 실행한 뒤 생성된 파일을 보면 다음과 같이 ES5 코드가 생성된 것을 볼 수 있다.

// out/lib.js
"use strict";

var sum = function sum(a, b) {
  return a + b;
};

console.log(sum(3, 4));


Source Map 설정

node.js처럼 ES2015를 직접 지원하는 환경이 아니라면 보통은 위처럼 변환을 한 뒤 변환한 코드를 사용해야 한다. 위 코드는 아주 간단하지만 이렇게 개발을 할 경우 오류를 추적하거나 디버깅을 하려면 변환된 ES5 코드와 원래의 ES2015 코드를 매핑해 주는 Source Map 설정을 해야 한다.(Source Map에 대해서는 이전에 작성한 자바스크립트와 커피스크립트에서 소스맵(source map) 사용하기 참고)

소스맵을 사용하기 위해 npm install --save-dev gulp-sourcemapsgulp-sourcemaps을 설치한 뒤 gulpfile.js을 다음과 같이 수정한다.

var gulp = require('gulp');
var sourcemaps = require('gulp-sourcemaps');
var babel = require('gulp-babel');

gulp.task('babel', function() {
  return gulp.src('src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(babel())
    .pipe(sourcemaps.write('./', {sourceRoot: '../src'}))
    .pipe(gulp.dest('out'));
});

기존에 babel로 변환하는 설정 사이에 소스맵 설정을 추가하면 소스파일을 경로를 설정한다. 이제 gulp babel을 실행하면 out 폴더 밑에 lib.js 파일 외에도 다음과 같은 lib.js.map 파일이 생성된다.

{
  "version":3,
  "sources":["lib.js"],
  "names":[],
  "mappings":";;AAAA,IAAI,GAAG,GAAG,SAAN,GAAG,CAAI,CAAC,EAAE,CAAC;SAAK,CAAC,GAAG,CAAC;CAAA,CAAC;;AAE1B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC",
  "file":"lib.js",
  "sourcesContent":["let sum = (a, b) => a + b;\n\nconsole.log(sum(3, 4));\n"],
  "sourceRoot":"../src"
}

소스맵 확인을 위해서 src/lib.js 파일을 다음과 같이 변경해 보자. 마지막 라인에서 고의로 오류를 발생시켰다. Node.js가 Source Map을 지원하지 않기 때문에 Source Map Support를 설치한 뒤 require('source-map-support').install();를 실행해야 Node.js에서 소스맵을 사용할 수 있다.

require('source-map-support').install();
let sum = (a, b) => a + b;

console.log(sum(3, 4));
throw new Error('Example Error');

만약 gulp에서 소스맵을 생성하는 설정을 넣지 않고 변환한 out/lib.js를 Node.js에서 실행하면 다음과 같은 오류 메시지가 발생한다.

$ node out/lib.js
7

/Users/outsider/projects/yak/es6/exmaple/out/lib.js:9
throw new Error('Example Error');
      ^
Error: Example Error
    at Object.<anonymous> (/Users/outsider/projects/yak/es6/exmaple/out/lib.js:9:7)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:134:18)
    at node.js:961:3

여기서는 오류메시지가 변환한 파일인 out/lib.js에서 나오므로 어느 부분에서 발생하는지를 알려면 개발자가 직접 원래의 코드인 ES2015를 살펴보아야 한다. 소스맵 설정이 되었다면 다음과 같이 오류메시지가 원래의 src/lib.js에서 라인 번호까지 한꺼번에 나타난다.

$ node out/lib.js
7

/Users/outsider/projects/yak/es6/exmaple/src/lib.js:5
throw new Error('Example Error');
      ^
Error: Example Error
    at Object.<anonymous> (/Users/outsider/projects/yak/es6/exmaple/src/lib.js:5:7)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:134:18)
    at node.js:961:3
2015/12/13 03:40 2015/12/13 03:40