babel - basic
배경
크로스 브라우징
브라우저 마다 사용하는 언어가 달라 프론트엔트 코드는 일관적이지 못할 때가 많다.
바벨은 ECMAScript2015+로 작성한 코드를 모든 브라우저에서 동작하도록 호환성을 지켜준다.
트랜스 파일과 빌드
변환 전후의 추상화 수준이 다른 빌드와는 달리 트랜스파일은 추상화 수준을 유지한 상태로 코드를 변환한다. 타입스크립트 → 자바스크립트, JSX → 자바스크립트처럼 트랜스파일 후에도 여전히 코드를 읽을 수 있다.
바벨의 기본 동작
npm install -D @babel/core @babel/cli
바벨은 세 단계로 빌드를 진행한다.
- 파싱(Parsing)
- 코드를 읽고 추상 구문 트리로 변환하는 단계
- 코드를 받아 토큰 별로 분해
- 변환(Transforming)
- 바벨의 플러그인이 담당
- 출력 (Printing)
플러그인
커스텀 플러그인
// my-babel-plugin.js:
module.exports = function myBabelPlugin() {
return {
visitor: {
Identifier(path) {
const name = path.node.name
// 바벨이 만든 AST 노드를 출력한다
console.log("Identifier() name:", name)
// 변환작업: 코드 문자열을 역순으로 변환한다
path.node.name = name.split("").reverse().join("")
},
},
}
}
사용법
npx babel --help
--plugins [list] A comma-separated list of plugin names.
활용
const 코드를 var로 변경하는 플러그인
module.exports = function myBabelPlugin() {
return {
visitor: {
VariableDeclaration(path) {
console.log("VariableDeclaration() kind:", path.node.kind); // const
if (path.node.kind === "const") {
path.node.kind = "var";
}
},
},
};
};
결과
$ npx babel app.js --plugins './my-babel-plugin.js'
// VariableDeclaration() kind: const
// var alert = msg => window.alert(msg);
실제 플러그인 사용하기
plugin-transform-block-scoping
npm install -D @babel/plugin-transform-block-scoping
결과
$ npx babel app.js --plugins @babel/plugin-transform-block-scoping
var alert = msg => window.alert(msg);
화살표 함수
npm install -D @babel/plugin-transform-arrow-functions
결과
$ npx babel app.js --plugins @babel/plugin-transform-block-scoping --plugins @babel/plugin-transform-arrow-functions
var alert = function (msg) {
return window.alert(msg);
};
엄격모드 “use strict”
npm install -D @babel/plugin-transform-strict-mode
결과
$ npx babel app.js --plugins @babel/plugin-transform-block-scoping --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-strict-mode
"use strict";
var alert = function (msg) {
return window.alert(msg);
};
babel.config.js
module.exports = {
plugins: [
"@babel/plugin-transform-block-scoping ",
"@babel/plugin-transform-arrow-functions ",
"@babel/plugin-transform-strict-mode",
],
};
결과
$ npx babel app.js
"use strict";
var alert = function (msg) {
return window.alert(msg);
};
프리셋
ECMAScript2015+으로 코딩할 때 필요한 플러그인을 일일이 설정하는 일은 무척 비효율적인 일이다.
목적에 맞게 여러가지 플러그인을 세트로 모아놓은 것을 "프리셋"이라고 한다.
커스텀 프리셋
my-babel-preset.js
module.exports = function myBabelPreset() {
return {
plugins: [
"@babel/plugin-transform-block-scoping",
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-strict-mode",
],
};
};
babel.config.js
module.exports = {
presets: ["./my-babel-preset.js"],
};
프리셋 사용하기
- preset-env
- preset-flow
- preset-react
- preset-typescript
preset-env
npm install -D @babel/preset-env
babel.config.js
module.exports = {
presets: ["@babel/preset-env"],
};
결과
$ npx babel app.js
"use strict";
var alert = function alert(msg) {
return window.alert(msg);
};
env 프리셋 설정과 폴리필
타켓 브라우저
브라우저 호환에 맞게끔 변환
module.exports = {
presets: [
[
"@babel/preset-env",
{
targets: {
chrome: "79",
ie: "11", // ie 11까지 지원하는 코드를 만든다
},
},
],
],
};
폴리필
바벨은 ECMAScript2015+를 ECMAScript5 버전으로 변환할 수 있는 것만 빌드한다.
그렇지 못한 것들은 "폴리필"이라고부르는 코드조각을 추가해서 해결
app.js
new Promise();
babel.config.js
useBuiltIns는 어떤 방식으로 폴리필을 사용할지 설정하는 옵션이다. "usage" , "entry", false 세 가지 값을 사용
바벨 문서의 useBuiltIns와 corejs 섹션을 참고
module.exports = {
presets: [
[
"@babel/preset-env",
{
useBuiltIns: "usage", // 폴리필 사용 방식 지정
corejs: {
// 폴리필 버전 지정
version: 2,
},
},
],
],
}
결과
$ npx babel app.js
"use strict";
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
var alert = function alert(msg) {
return window.alert(msg);
};
new Promise();
웹팩으로 통합
npm install -D babel-loader
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\\.js$/,
exclude: /node_modules/,
loader: "babel-loader", // 바벨 로더를 추가한다
},
],
},
}
※ 출저
728x90
'Study > webpack' 카테고리의 다른 글
webpack@4 - 개발서버,API,HMR,최적화 (0) | 2022.06.05 |
---|---|
webpack@4 - lint,prettier (0) | 2022.06.04 |
webpack@4 - plugin (0) | 2022.06.04 |
webpack@4 - loader (0) | 2022.06.04 |
webpack@4 - 엔트리/아웃풋 (0) | 2022.06.04 |