브라우져마다 사용하는 언어가 달라서 프론트엔드 코드는 일관적이지 못할 때가 많다
크로스브라우징
의 혼란을 해결해 줄 수 있는 것이 바로 바벨
ECMAScript2015+로 작성한 코드를 모든 브라우저
에서 동작하도록 호환성
을 지켜준다
타입스크립트, JSX처럼 다른 언어로 분류되는 것도 포함한다
이렇게 변환하는 것을 트랜스파일
한다 라고 표현
타입스크립트 -> 자바스크립트
JSX -> 자바스크립트
처럼 트랜스파일 후 여전히 코드를 읽을 수 있다
바벨 설치
npm install @babel/core @babel/cli
const alert = msg => window.alert(msg);
ES6 문법인 화살표함수
와 const
를 사용해서 코드를 작성한다
ES6를 지원하지 않는 브라우저 같은 경우는 이 코드를 인식하지 못한다
바벨을 통해서 모든 브라우저에서 인식할 수 있도록 변환해보자
바벨을 실행할 때는 node_modules/.bin/babel
명령어를 통해 실행해도 되고 npx
를 사용해 실행할 수 있다
npx babel app.js
바벨은 세 단계로 빌드를 진행한다
파싱
은 코드를 받아가지고 각 토큰별로 다 분해한다
예를들면 위 코드에서 const
alert
=
... 이런식으로 분해한다
변환
은 ES6로 되어있는 코드를 ES5코드로 변환한다
마지막으로 변경된 결과물을 출력
하는 것으로 바벨은 작업을 완료한다
하지만 결과를 보면 빌드 이전과 변한게 없다.
npx babel app.js
const alert = msg => window.alert(msg); // 빌드 결과
이는 파싱은 했지만 변환 작업을 하지 않은 것
이다
변환하지 않고 출력했기 때문에 결과가 이전과 동일한 것이다
바벨은 파싱
과 출력
만 담당하고 변환
작업은 플러그인
이 담당한다
module.exports = function myplugin() {
return {
visitor: {
VariableDeclaration(path) {
console.log("VariableDeclaration() kind:", path.node.kind); // const
// const => var 변환
if (path.node.kind === "const") {
path.node.kind = "var";
}
},
},
};
};
VariableDeclaration
메소드는 파싱된 결과를 path
라는 객체로 받는다
path.node.kind 값이 'const'이면 'var'로 변환해주는 코드이다
ES6문법인 const
를 ES5문법인 var
로 변환해주는 플러그인이다
이 플러그인을 가지고 다시 바벨을 실행시켜보자
플러그인 사용법은 --plugins 옵션
에 플러그인을 추가하면 된다
npx babel --help
--plugins [list]
// 바벨 실행
npx babel app.js --plugins ./my-babel-plugin.js
// 빌드 결과
VariableDeclaration() kind: const
var alert = msg => window.alert(msg);
이러한 결과를 만드는 것이 block-scoping
플러그인이다
const, let 처럼 블록 스코핑을 따르는 예약어를 함수 스코핑을 사용하는 var로 변경한다
npm install -D @babel/plugin-transform-block-scoping
해당 플러그인을 사용해서 다시 app.js를 트랜스파일 해보자
npx babel app.js --plugins @babel/plugin-transform-block-scoping
var alert = msg => window.alert(msg); // 실행 결과
커스텀 플러그인과 같은 결과를 보인다
ES6인 화살표 함수도 arrow-functions
플러그인을 사용해서 일반 함수로 변경할 수 있다
npm install -D @babel/plugin-transform-arrow-functions
npx babel app.js --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-block-scoping
// 실행 결과
var alert = function (msg) {
return window.alert(msg);
};
const, let 키워드가 var로 변환되었고, 화살표 함수도 일반 함수로 변환이 되었다
ECMAScript5 부터 지원하는 엄격 모드를 사용하는 것이 안전하기 때문에 use strict
구문을 추가한다
이는 strict-mode
플러그인을 사용한다
npm install -D @babel/plugin-transform-strict-mode
npx babel app.js --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-block-scoping --plugins @babel/plugin-transform-strict-mode
//실행 결과
"use strict";
var alert = function (msg) {
return window.alert(msg);
};
상단에 "use strict"; 구문이 추가된 것을 확인할 수 있다
플러그인이 많아질수록 커맨드라인이 길어지므로 기본 설정파일인 babel.config.js
를 작성하자
module.exports = {
plugins: [
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-strict-mode",
],
};
babel.config.js를 작성했으면 이제 바벨을 실행할 때 간편하게 npx babel app.js
만 입력해도 플러그인이 전부 적용된다
npx babel app.js
// 실행 결과
"use strict";
var alert = function (msg) {
return window.alert(msg);
};
ES5+으로 코딩할 때 필요한 플러그인을 일일이 설정하는 일은 매우 번거롭다
목적에 맞게 여러가지 플러그인을 세트로 모아둔 것
을 프리셋
이라고 한다
위에서 사용한 세 개의 플러그인을 하나의 프리셋으로 만들어보자
module.exports = function myBabelPreset() {
return {
plugins: [
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-strict-mode",
],
};
};
plugins 프로퍼티에 플러그인을 담은 배열이 들어있는 객체를 반환하는 myBabelPreset 함수를 만들고 babel.config.js에 presets
에 추가해준다
module.exports = {
presets: ["./my-babel-preset.js"],
};
기존의 plugins를 지우고 presets를 추가한다
presets에는 프리셋 배열이 들어가는데 위에 작성한 커스텀 프리셋을 추가한다
npx babel app.js
// 실행 결과
"use strict";
var alert = function (msg) {
return window.alert(msg);
};