게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌13 - ECMAScript - 8년 전 등록 / 6년 전 수정

BabelJS(바벨)

7버전

안녕하세요! 이번 시간에는 바벨(BabelJS)에 대해 알아보겠습니다! 바벨 자체는 ECMAScript가 아닙니다. 하지만 이 카테고리에 있는 이유는 바로 ES2015+ 문법을 실제로 사용할 수 있게 해주기 때문입니다.

ES2015+ 문법은 에버그린 브라우저만 지원하는 기능이기 때문에 구형 브라우저(IE라든가... IE라든가...)와는 호환이 안 된다는 단점이 있습니다. 아직도 윈도우7을 쓰는 컴퓨터가 많기 때문에 IE 점유율이 상당한데요. ES2015+ 문법을 구형 브라우저에서 사용하고 싶다면 어떻게 해야 할까요? 그냥 포기해야 하는 걸까요?

아닙니다. ES2015+ 문법을 사용한 코드를 예전 ES5 자바스크립트 코드로 바꿔주는 도구들이 있습니다. 그중에서 가장 유명한 도구가 바벨입니다. 바벨탑의 이름을 딴 것 같네요(왜 이름을 바벨로 지었는지 아시겠죠?). 바벨을 사용하려면 npm을 사용하여

npm install --save-dev @babel/cli @babel/core @babel/preset-env @babel/preset-stage-2

하여 설치해주어야 합니다. 바벨 7버전부터는 모든 바벨 패키지들이 @babel이라는 네임스페이스 안에 속하게 되었습니다. npm을 모른다면 이 강좌를 참조하세요. 

6버전까지는 다음과 같이 했습니다. 이렇게 분산된 패키지들은 @babel이라는 네임스페이스로 모아준 것입니다.

npm install --save-dev babel-cli babel-core babel-preset-env babel-preset-stage-2  

@babel/cli@babel/core @babel/preset-env, @babel/preset-stage-2 네 패키지를 설치하였습니다. 이제 명령 프롬프트에서 babel 명령어를 사용할 수 있습니다(@babel/cli의 역할). 하지만 직접 명령어를 치기보다는 npm과 package.json 파일을 사용하여 하는 게 더 간편합니다.

우선 .babelrc라는 파일을 만들어 설치한 preset을 연결해줍니다. .babelrc는 바벨에 대해 설정을 하는 파일입니다. 여기에 preset이나 plugin을 연결하면 됩니다. preset은 여러 플러그인의 모음집입니다.

유명한 preset으로는 react나 es2015, es2016, es2017, env, stage-0, stage-1, stage-2, stage-3 등이 있습니다. 7버전부터 stage-0, stage-1, stage-2, stage-3은 deprecated되었습니다. 앞으로는 새로운 스펙은 프리셋 대신 플러그인 형식으로 넣어야 합니다.

react 프리셋은 react 환경(jsx)을 위한 프리셋이고, es2015는 ES2015 문법을 사용할 수 있게 도와주는 플러그인들의 프리셋입니다.

env 프리셋은 한 술 더 떠서 특정한 문법 버전을 입력할 필요 없이, 타겟 브라우저를 입력하면 알아서 사용자가 환경에 맞춰 최신 EcmaScript를 사용할 수 있게 해줍니다. env를 정말 추천합니다. stage-0부터 3까지는 EcmaScript 스펙 중에서 비공식 실험적인 기술들을 사용할 수 있게 해주는 프리셋입니다. stage들은 deprecated되었습니다.

stage-2까지는 그나마 안정적이고, stage-0과 stage-1은 언제든지 바뀔 수 있는 기술들이라 사용 시 주의가 필요합니다. 저는 stage-2를 주로 사용합니다. stage-1이나 stage-0은 stage-2를 포함하고 있지만 자주 쓰이는 기능이 아니라 사용하지 않습니다. 플러그인과 preset에 대한 자세한 설명은 여기 있습니다.

.babelrc

{
  "presets": [
    ["@babel/preset-env", { "targets": { "browsers": ["last 2 versions", ">= 5% in KR"] } }],
    ["@babel/preset-stage-2", { "decoratorsLegacy": true }]
  ]
}

env와 stage-2를 쓰도록 설정한 것인데요. 각각 배열 안에 배열로 묶여져 있습니다. 배열의 두 번째 요소가 env와 preset에 대한 설정입니다. targets 부분입니다.

targets 옵션을 살펴보면, 브라우저들에 대해서는 최신 두 버전(IE는 10과 11, 크롬과 파이어폭스, 사파리, 엣지는 최신 두 버전)과 한국에서 5% 이상 점유율을 차지하는 브라우저를 모두 지원하라고 설정해준 겁니다. 저렇게만 쓰면 babel이 알아서 최신 자바스크립트 코드를 지정한 targets에 맞게 호환되는 자바스크립트 코드로 바꿔줍니다. 정말 편하죠!

만약 브라우저 대신 노드 환경에서 바벨을 쓰고 싶다면(극히 드물지만, 리액트 서버사이드 렌더링을 하는 것과 같은 경우에 쓰기도 합니다) { targets: { node: 'current' } } 등을 지정하면 됩니다.

decoratorsLegacy는 stage-2의 decorators를 사용하기 위한 옵션입니다.

그리고 package.json에는 scripts 부분에 바벨로 컴파일하는 부분을 기재해줍니다.

package.json

{
  "scripts": {
    "build": "babel src -d lib"
  }
}

npm run build 명령을 수행할 때 babel을 실행하고, src 폴더에 있는 최신 자바스크립트 코드를 컴파일하여 결과를 lib 폴더에 넣으라는 뜻(-d 옵션이 결과를 저장할 경로를 의미합니다.)입니다. 컴파일하는 과정에서 알아서 .babelrc 파일을 읽어 옵션을 적용합니다.

이제 구형 브라우저에서는 src 폴더 대신 lib 폴더에 있는 자바스크립트 파일을 사용하면 됩니다. 코딩은 src 폴더에서 ES2015 스타일로 하면 되고요. 당연한 소리이지만 폴더 이름은 src, lib으로 고정되어있는 것이 아니라 사용자 마음대로입니다. 추가적인 바벨 명령어에 대한 자세한 설명은 여기를 참조하세요.

babel-polyfill

바벨을 사용하면 새로운 문법을 구형 자바스크립트 문법으로만 바꿔줍니다. 문법만 바꿔주면 됐지 뭘 더 바라냐고요? 바벨 그 자체로는 ES2015의 새로운 객체(Promise, Map, Set 등등)과 메소드(Array.find, Object.assign 등등)을 사용할 수 없습니다. 왜냐하면 ES2015에서 처음 생긴 거라 구형 자바스크립트에는 그에 상응하는 코드가 없거든요. 그래서 babel-polyfill을 설치해야 새로운 기능을 사용할 수 있습니다.

@babel/polyfill 패키지를 먼저 설치합니다. 6버전까지는 babel-polyfill이었습니다.

npm install @babel/polyfill

ES2015 문법을 사용하는 파일 가장 윗부분에 다음 줄을 추가합니다. 단, 폴리필은 하나의 프로젝트에 한 번만 사용해야 합니다. 그렇지 않으면 충돌이 발생합니다. 따라서 가장 먼저 로딩되는 스크립트 제일 위에 추가하도록 합시다.

import '@babel/polyfill';

구문을 넣으면 babel이 컴파일할 때 알아서 적용합니다. 다음은 예시입니다.

import '@babel/polyfill';
import ...
const val = Object.assign({ a: '1' }, { a: 'b' });
export default val;

웹팩을 사용한다면 파일에 import '@babel/polyfil';하는 대신 웹팩 설정 파일 entry에 적어도 됩니다. 다음과 같이요.

webpack.config.js

{
  entry: ['@babel/polyfill', './app.js'],
}

이렇게요. 웹팩이 알아서 app.js에 polyfill을 적용해줍니다.

간단하죠? @babel/preset-env와 @babel/polyfill 패키지만 있으면 ES2015+의 모든 기능을 사용할 수 있습니다. 다음 시간에는 새로 추가된 메소드들을 알아봅시다.

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

11개의 댓글이 있습니다.
6년 전
polyfill 소개하는부분에 poyfill이라고 오타가 난것같아요!
6년 전
create react app 에서 .babelrc 파일을 어디에 위치시켜야하나요?
6년 전
babylon은 babel의 최신 버전인 건가요?
6년 전
바빌론은 바벨의 코드 파서입니다. 그냥 부품 중 하나에요.
6년 전
polyfill 이란게 무슨뜻인가요?
6년 전
없는 기능을 추가해주는 코드입니다.
6년 전
webpack 을 사용하면서 babel-loader가 babel-core를 필요로 하는데 babel7을 사용하면서 @babel/core 를 babel-loader가 인식을 못해 충돌이 일어납니다. 어쩔수 없이 다시 babel6버전대로 다시 왔는데 혹시 해결 방법이 있을까요?
6년 전
babel-loader도 babel-loader@^8.0.0-beta를 설치하셔야 합니다. 웹팩 강좌에 있습니다
7년 전
웹팩, 바벨, 모듈이란 개념이 섞여서 혼란스러웠는데 감사합니다! 바벨 preset부분에서 ["> 5% in KR"] \u003c-- 되게 신기하네용.. 그럼 바벨 어딘 가에 국가명이랑 사용비율을 인식하고 있다는 뜻인가요? 엄청 궁금하네요
7년 전
네 caniusedb였나 브라우저 호환성이나 국가별 사용량 이런거 모아둔 디비가 있었던걸로 압니다. 아, 국가별 사용량은 browserslist인거 같네요.
7년 전
IE라든가... IE라든가.. 이거 오타 아니죠 ㅋㅋ 빵 터졌네요 ㅋㅋ
여러가지 좋은 정보 감사드립니다.
7년 전
감사합니다~
7년 전
안녕하세요.
유익한 강좌 도움이 많이 되었습니다.

babel-preset-env만 설치했을 때는 babel-polyfill의 기능이 동작안했는데
babel-polyfill을 따로 설치하고 나서는 잘 되네요.
아마도 babel-preset-env에 babel-polyfill이 포함이 안된 것이 아닐까 싶은데, 맞나요?
7년 전
네네 별도인거 같네요. 새로운 객체같은 것들은 polyfill로 만들어줘야합니다.
7년 전
원래 es6 클래스에 메서드로 화살표함수 못쓰지 않나요??
그런데.. react에서는 this 바인딩을 화살표 함수로 간단히 처리 하더라구요.
그게 리액트가 해주는건가요?
바벨이 해주는 건가요?
바벨이 해준다면..
class 안에서 화살표함수를 메서드로 쓰는게.. 표준인건가요?
제가 테스트했을 때에는 바벨을 안써서? 인지 문법 에러가 났습니다.
화살표함수는 Babel의 stage-2-preset 지원 된다 검색을 본거 같은데요..
stage-2-preset는 그냥 라이블러리 같은건가요?
7년 전
Stage2는 공식 스펙 후보군입니다. 제 es 강좌를 참조하세요. 바벨 쓰셔야됩니다
7년 전
솔직히 바벨 설정을 남들보고 그냥 따라 설정하기 바빳지 뭐가뭔지 몰랐는데 제대로 알아갑니다 감사합니다
7년 전
안녕하세요 글 보고 질문이 있어서 글 남깁니다.. ES6로 코드를 작성하다가 요구사항변경으로 익스10도 호환가능해야 한다고해서 babel로 제 코드를 컴파일을 하려고하는데, Map을 사용하였기 때문에 import 'babel-polyfill';을 제 스크립트에 추가해서 작성하였습니다. 그런데 컴파일 후 파일에 require(
'babel-polyfill') 이라는 코드가 생겨서 그냥 생성해주는가보다 하고 ie10에 맞춰놓고 테스트를 했는데 require가 정의되지 않았습니다. 라는 오류가 떳습니다. 혹시 제가 추가적으로 해야할 설정이 남은건가요? .bablerc에는 preset 속성만 es2015 , stage-2 만 주었습니다.
7년 전
바벨 폴리필을 import하지 마시고, script 파일을 구하셔서 스크립트로 넣어보세요.
7년 전
감사합니다. script를 import해서 해결했습니다. 저와 같은 문제가있으신분들은 프로젝트 내에 node_modules 디렉토리 안에 babel-polyfill/dist 디렉토리를 보면 pollyfill.js가 있습니다. 이걸 먼저 태그로 등록을 하시면 작동을합니다. 물론 import 'babel-polyfill' 이걸 사용하면 안됩니다. 이글을보고 공식홈피를 보니까 이해가 더 잘되네요