바벨(Babel)과 폴리필(Polyfill)

2023년 4월 4일

우리가 웹 개발을 하다보면 한번쯤은 BabelPolyfill이라는 용어를 들어본 적이 있을 것이다. 필자도 들어본 것 같긴한데 정확히 무엇인지는 모르겠어서 정리해보려고 한다.😁

이번 포스팅에서는 BabelPolyfill의 정의와 각각의 역할에 대해 알아볼 것이다.

Babel이란?

먼저 조금 더 익숙한 Babel에 대해 알아보자.

Babel은 자바스크립트의 새로운 문법을 사용할 수 있게 해주는 도구이다. 즉, Babel은 최신 자바스크립트 문법을 지원하지 않는 브라우저에서도 최신 자바스크립트 문법을 사용할 수 있게 해주는 도구이다.

왜 컴파일러라고 할까?🤔

공식사이트에 따르면 Babel은 자바스크립트 컴파일러라고 한다.

Quote

Babel is a JavaScript compiler.

저수준의 언어로 변환하는 것이 컴파일이라고 하는 것 아닌가? 바벨은 자바스크립트를 자바스크립트로 변환하는 것이 아닌가? 그렇다면 바벨은 컴파일러라고 할 수 있을까? 라는 의문이 생겼다. 혹시나 필자처럼 생각하는 사람이 있을 수 있기 때문에 기록을 남기려고 한다.😁

현대에는 컴파일이라는 용어가 넓은 의미로 사용된다. 전통적으로는 고급 언어를 기계어로 변환하는 것을 의미했지만, 지금은 소스 코드를 다른 형태로 변환하는 거의 모든 작업을 포함하게 되었다. 이 확장된 의미에서는 트랜스파일링(transpiling)도 컴파일링의 한 형태로 간주된다.

따라서 Babel은 엄밀히 말하면 트랜스파일러지만, 위와 같은 이유로 자바스크립트 컴파일러라고 부른다.

Babel은 왜 필요할까?

그렇다면 왜 Babel이 필요할까? 프론트엔드 기술은 빠르게 발전하고 있다. 그리고 ECMAScript는 매년 새로운 자바스크립트 문법을 추가하고 있다. 이렇게 새로운 문법이 추가되면서 브라우저는 새로운 문법을 지원하지 못하는 경우가 생긴다. 이런 경우에 Babel을 사용하면 새로운 문법을 사용할 수 있다.

예를 들어, ES6에서 도입된 arrow functionclass 같은 문법을 일반 함수나 프로토 타입을 이용한 함수로 변환해주는 역할을 한다.

// ES6 문법
class Person {
constructor(name) {
this.name = name;
}
sayHello() {
console.log(`Hello, ${this.name}!`);
}
}
const person = new Person('John');
person.sayHello();
// Babel 변환 후
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log('Hello, ' + this.name + '!');
};
var person = new Person('John');
person.sayHello();

Polyfill이란?

mdn에서는 polyfill을 다음과 같이 정의하고 있다.

Quote

polyfill은 기본적으로 지원하지 않는 이전 브라우저에서 최신 기능을 제공하는 데 필요한 코드 (일반적으로 웹의 JavaScript)입니다.

polyfill은 우선 브라우저에서 지원되는 JavaScript 기능을 확인한다. 브라우저가 특정 기능을 지원하지 않는 경우, 해당 기능을 제공하는 코드를 추가적으로 제공하여 브라우저가 해당 기능을 "이해"할 수 있게 만든다.

예를 들어, Promise는 ES6에서 도입된 기능이지만, ES6를 완벽하게 지원하지 않는 구버전 브라우저에서는 이 기능을 사용할 수 없다. 이런 경우, polyfill을 구버전 브라우저에서도 사용할 수 있도록 Promise를 구현한다. 아래 코드를 보자.

// Promise를 사용하는 코드
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('Success');
}, 2000);
});
promise
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.error(error);
});

만약 구버전 브라우저에서 위 코드를 실행하면 Promise가 정의되지 않았다는 오류가 발생한다. 이런 경우 polyfill은 다음과 같이Promise를 구현한다.

// Promise 폴리필
if (!window.Promise) {
window.Promise = function (executor) {
var self = this;
self.onResolve = null;
self.onReject = null;
function resolve(value) {
if (self.onResolve) {
self.onResolve(value);
}
}
function reject(reason) {
if (self.onReject) {
self.onReject(reason);
}
}
executor(resolve, reject);
};
}

Babel과 Polyfill은 각각 어떤 역할을 할까?

babel은 브라우저가 이해하지 못하는 새로운 문법(최신 자바스크립트 문법)을 이해할 수 있게 변환해주는 역할을 하고, polyfill브라우저가 지원하지 않는 기능을 지원하는 코드를 제공해주는 역할을 한다

새로운 문법은 babel에 의해 컴파일될 수 있다. 새로운 문법에는 다음과 같은 것들이 있다.

  • arrow function
  • class
  • template literal
  • const/let

babel에 의해 컴파일될 수 없고, polyfill이 필요한 것은 다음과 같다. 이들은 브라우저가 지원하지 않는 기능, 즉 ES5의 global namespace(window)에 존재하지 않는 것들이다.

  • 새로운 객체 (Promise, Set, Map, ...)
  • 새로운 메서드 (Array.prototype.includes, Object.assign,...)
  • 새로운 함수 (fetch, ...)

정리해보면 ES6 이상의 새로운 문법은 babel에 의해 컴파일될 수 있지만, ES5의 global namespace(window)에 존재하지 않는 것은 polyfill이 필요하다.

Quote

여기에 polyfill이 필요한 기능들이 정리되어 있다. 이를 제외한 나머지 기능들은 Babel로 컴파일이 가능하다.


Quote

webpack으로 React 개발 환경 설정에 대한 내용은 Webpack + React + TypeScript Boilerplate에서 확인할 수 있다.

Quote

Babel의 적용 방법과 원리에 대한 내용은 Babel 적용하며 이해하기(with. React, TS)에서 확인할 수 있다.

Quote

Polyfill의 적용 방법은 Polyfill 적용하며 이해하기(with. React, TS)에서 확인할 수 있다.


참고

Kihoon
기록하는 프론트엔드 개발자

이전 포스트
웹팩(webpack) 이란?
다음 포스트
[프로그래머스] 연속된 부분 수열의 합 (JavaScript)