우선 폴리필이란 단어의 뜻은 충전솜이란 말을 의미한다.
Promise, Array.prototype.includes() 같은 새로운 문법이 아닌 새로운 기능들은 바벨을 통해 트랜스파일링 되지 못한다. 충전솜과같은 역할을 한다고 해서 polyfill 이라고 부른다.기본적으로 전역공간에 폴리필이 만든 함수나 객체를 채워넣는 방식으로 구동된다.
이는,곧 전역공간이 오염되고, 다른 코드들까지 영향을 준다는 의미이다.
폴리필에서 Promise를 정의해서 채워넣었는데 다른 코드에서는 이미 ES6에서 정의된 Promise를 참조해서 사용하는경우 충돌의 예시가 된다.
@babel/plugin-transform-runtime 폴리필을 사용하면 전역객체에 충돌을 방지하기 위해 바벨이 es6+의 문법들을 자체 구현한 함수로 트랜스파일링 해준다.
[1,2,3].includes와 같이 인스턴스의 메소드는 제대로 트랜스파일링 되지 않는 이슈가 있다.axios는 전역공간에 선언된 Promise가 있어야 제대로 동작하는데 이 플러그인은 트랜스파일링 과정에서 자체 구현된 함수로 변경되기 때문에 전역공간에 Promise를 채우지 않는다. 그래서 아래처럼 node_modules내부에 있는 axios가 런타임에 트랜스파일 될 수 있도록 웹팩 설정을 커스텀해줘야 한다.include: [
/src\/js/,
/node_modules\/axios/
],이 런타임 폴리필 방식은 제한사항이 있으므로 완벽하게 폴리필을 넣어주고 싶은 경우 다른 방식을 사용해야 한다.
core-js는 기존 @babel/polyfill의 전역 공간 오염 문제와 @babel/plugin-transform-runtime의 인스턴스 메서드 문제를 모두 해결한 최신 폴리필 방식입니다.
✅ @babel/plugin-transform-runtime만 사용하면?
✅ @babel/polyfill 사용하면?
✅ core-js를 사용하면?
// 최신 ES6+ 기능
const arr = [1, 2, 3];
console.log(arr.includes(2)); // ✅ ES7 기능 (IE11 미지원)
console.log(Promise.resolve("완료!")); // ✅ ES6 Promise
class Person {
constructor(name) {
this.name = name;
}
}
const person = new Person("홍길동");
console.log(person.name);
npm install --save core-js
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "entry",
"corejs": 3
}]
],
}
📌
useBuiltIns:usage옵션 설명
- 이 옵션을 사용하면, 코드에서 실제로 사용된 기능만 골라서 폴리필됩니다.
- 즉, 필요한 폴리필만 추가하므로, 번들 크기가 줄어듭니다.
- enty 옵션을 사용하면 모든 기능이 폴리필됩니다.
npx babel script.js --out-file lib/script.js
"use strict";
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
// 최신 ES6+ 기능
var arr = [1, 2, 3];
console.log(arr.includes(2)); // ✅ ES7 기능 (IE11 미지원)
console.log(Promise.resolve("완료!")); // ✅ ES6 Promise
var Person = /*#__PURE__*/_createClass(function Person(name) {
_classCallCheck(this, Person);
this.name = name;
});
var person = new Person("홍길동");
console.log(person.name);

그렇다면 core-js가 어떻게 인스턴스 메서드 미변환 문제와 전역 오염 문제를 해결한걸까?
useBuiltIns: "usage"옵션은 코드에서 실제로 사용된 기능만 골라서 폴리필을 추가.- includes를 사용하면 core-js/modules/es.array.includes.js만 추가됨 => 필요한 기능만 core-js가 동적으로 추가해주기 때문에, 오염을 방지할 수 있다.
cat node_modules/core-js/modules/es.array.includes.js

