ES5 번들을 부풀리는 3가지 JavaScript 기능
나쁜 오래된 브라우저
슬프지만 사람들은 여전히 오래된 브라우저를 사용합니다. 여기서 IE에 대해 구체적으로 말하는 것이 아닙니다. 일부 사람들은 휴대폰에서 자동 업데이트를 끄고 더 이상 신경 쓰지 않습니다. 참으로 슬프다 😥
내가 신경써야 하나?
일부 앱을 개발하는 경우에 따라 다릅니다. 당신은 당신의 사용자를 더 잘 알고 있습니다. 아마도 그들은 기술적으로 발전했고 단순히 오래된 브라우저를 사용하지 않을 것입니다. 또는 IE 사용자 비율이 작고 비용을 지불하지 않으므로 완전히 무시할 수 있습니다.
그러나 JS lib를 작성하는 중이라면 반드시 해야 합니다. 현재로서는 libs가 일반적으로 ES5로 트랜스파일되어 어떤 환경에서도 작동할 수 있도록 배포됩니다(그러나 폴리필을 요구하는 것은 괜찮다고 가정함).
자, 멋진 ES6+ 코드를 크고 부풀려진 ES5로 바꾸는 JS 기능이 무엇인지 봅시다!
1. 발전기
아마도 가장 유명한 ES5 적대적 구성일 것입니다. 에어비앤비has a separate note가 올라올 정도로 눈에 띈다.
입력
function* gen() {
yield 1
yield 2
}
TypeScript 출력
var __generator = /* Somewhat long helper function */
function gen() {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
_a.sent();
return [4 /*yield*/, 2];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}
TypeScript에 대한 좋은 소식은 번들당 한 번 __generator
와 같은 도우미 함수를 정의하는 것입니다. 그러나 생성기 정의는 항상 소스만큼 좋지 않은 유한 오토마타로 변환됩니다 😕
바벨 출력
require("regenerator-runtime/runtime.js");
var _marked = /*#__PURE__*/regeneratorRuntime.mark(gen);
function gen() {
return regeneratorRuntime.wrap(function gen$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 1;
case 2:
_context.next = 4;
return 2;
case 4:
case "end":
return _context.stop();
}
}
}, _marked);
}
Babel은 더 나아가 모든 생성기 런타임을 다른 모듈로 이동합니다. 불행히도 꽤 큽니다 🐘
무엇을 할까요?
이터러블을 사용합니다. 하지만 조심하세요. 코드를 부풀릴 수 있는 방법도 있습니다 😉
2. 비동기 대기
뭐? Promise에 대한 구문 설탕이 아닌가요? 보자!
입력
export async function fetchExample() {
const r = await fetch('https://example.com')
return await r.text();
}
TypeScript 출력
var __awaiter = /* Some convoluted JS code */
var __generator = /* We saw it already! */
function fetchExample() {
return __awaiter(this, void 0, void 0, function () {
var r;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetch('https://example.com')];
case 1:
r = _a.sent();
return [4 /*yield*/, r.text()];
case 2: return [2 /*return*/, _a.sent()];
}
});
});
}
발전기보다 더 나쁘다! async-await
실제로 Promise에서 추가로 일시 중단되는 생성기입니다.
바벨 출력
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
require("regenerator-runtime/runtime.js");
function asyncGeneratorStep/* Like __awaiter */
function _asyncToGenerator/* Yet another converter */
function fetchExample() {
return _fetchExample.apply(this, arguments);
}
function _fetchExample() {
_fetchExample = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var r;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return fetch('https://example.com');
case 2:
r = _context.sent;
_context.next = 5;
return r.text();
case 5:
return _context.abrupt("return", _context.sent);
case 6:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return _fetchExample.apply(this, arguments);
}
Babel은 TypeScript와 마찬가지로 async-await
를 생각합니다. 몇 가지 추가 항목이 있는 생성기이므로 가져오기뿐만 아니라 일부 도우미 함수도 생성합니다.
무엇을 할까요?
간단한 Promise 체인을 사용하십시오. 너무 "전통적"으로 보일 수 있지만 어떤 것으로도 잘 변환됩니다.
3. 반복 가능한 반복
여러 JS 구성으로 인해 반복자 반복이 발생합니다. for-of
루프, 반복 가능한 확산 및 반복 가능한 구조 해제.
그러나 이 기능에 대한 몇 가지 좋은 소식이 있습니다.
일부 앱을 개발하는 경우에 따라 다릅니다. 당신은 당신의 사용자를 더 잘 알고 있습니다. 아마도 그들은 기술적으로 발전했고 단순히 오래된 브라우저를 사용하지 않을 것입니다. 또는 IE 사용자 비율이 작고 비용을 지불하지 않으므로 완전히 무시할 수 있습니다.
그러나 JS lib를 작성하는 중이라면 반드시 해야 합니다. 현재로서는 libs가 일반적으로 ES5로 트랜스파일되어 어떤 환경에서도 작동할 수 있도록 배포됩니다(그러나 폴리필을 요구하는 것은 괜찮다고 가정함).
자, 멋진 ES6+ 코드를 크고 부풀려진 ES5로 바꾸는 JS 기능이 무엇인지 봅시다!
1. 발전기
아마도 가장 유명한 ES5 적대적 구성일 것입니다. 에어비앤비has a separate note가 올라올 정도로 눈에 띈다.
입력
function* gen() {
yield 1
yield 2
}
TypeScript 출력
var __generator = /* Somewhat long helper function */
function gen() {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
_a.sent();
return [4 /*yield*/, 2];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}
TypeScript에 대한 좋은 소식은 번들당 한 번 __generator
와 같은 도우미 함수를 정의하는 것입니다. 그러나 생성기 정의는 항상 소스만큼 좋지 않은 유한 오토마타로 변환됩니다 😕
바벨 출력
require("regenerator-runtime/runtime.js");
var _marked = /*#__PURE__*/regeneratorRuntime.mark(gen);
function gen() {
return regeneratorRuntime.wrap(function gen$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 1;
case 2:
_context.next = 4;
return 2;
case 4:
case "end":
return _context.stop();
}
}
}, _marked);
}
Babel은 더 나아가 모든 생성기 런타임을 다른 모듈로 이동합니다. 불행히도 꽤 큽니다 🐘
무엇을 할까요?
이터러블을 사용합니다. 하지만 조심하세요. 코드를 부풀릴 수 있는 방법도 있습니다 😉
2. 비동기 대기
뭐? Promise에 대한 구문 설탕이 아닌가요? 보자!
입력
export async function fetchExample() {
const r = await fetch('https://example.com')
return await r.text();
}
TypeScript 출력
var __awaiter = /* Some convoluted JS code */
var __generator = /* We saw it already! */
function fetchExample() {
return __awaiter(this, void 0, void 0, function () {
var r;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetch('https://example.com')];
case 1:
r = _a.sent();
return [4 /*yield*/, r.text()];
case 2: return [2 /*return*/, _a.sent()];
}
});
});
}
발전기보다 더 나쁘다! async-await
실제로 Promise에서 추가로 일시 중단되는 생성기입니다.
바벨 출력
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
require("regenerator-runtime/runtime.js");
function asyncGeneratorStep/* Like __awaiter */
function _asyncToGenerator/* Yet another converter */
function fetchExample() {
return _fetchExample.apply(this, arguments);
}
function _fetchExample() {
_fetchExample = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var r;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return fetch('https://example.com');
case 2:
r = _context.sent;
_context.next = 5;
return r.text();
case 5:
return _context.abrupt("return", _context.sent);
case 6:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return _fetchExample.apply(this, arguments);
}
Babel은 TypeScript와 마찬가지로 async-await
를 생각합니다. 몇 가지 추가 항목이 있는 생성기이므로 가져오기뿐만 아니라 일부 도우미 함수도 생성합니다.
무엇을 할까요?
간단한 Promise 체인을 사용하십시오. 너무 "전통적"으로 보일 수 있지만 어떤 것으로도 잘 변환됩니다.
3. 반복 가능한 반복
여러 JS 구성으로 인해 반복자 반복이 발생합니다. for-of
루프, 반복 가능한 확산 및 반복 가능한 구조 해제.
그러나 이 기능에 대한 몇 가지 좋은 소식이 있습니다.
function* gen() {
yield 1
yield 2
}
var __generator = /* Somewhat long helper function */
function gen() {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
_a.sent();
return [4 /*yield*/, 2];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}
require("regenerator-runtime/runtime.js");
var _marked = /*#__PURE__*/regeneratorRuntime.mark(gen);
function gen() {
return regeneratorRuntime.wrap(function gen$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return 1;
case 2:
_context.next = 4;
return 2;
case 4:
case "end":
return _context.stop();
}
}
}, _marked);
}
뭐? Promise에 대한 구문 설탕이 아닌가요? 보자!
입력
export async function fetchExample() {
const r = await fetch('https://example.com')
return await r.text();
}
TypeScript 출력
var __awaiter = /* Some convoluted JS code */
var __generator = /* We saw it already! */
function fetchExample() {
return __awaiter(this, void 0, void 0, function () {
var r;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, fetch('https://example.com')];
case 1:
r = _a.sent();
return [4 /*yield*/, r.text()];
case 2: return [2 /*return*/, _a.sent()];
}
});
});
}
발전기보다 더 나쁘다!
async-await
실제로 Promise에서 추가로 일시 중단되는 생성기입니다.바벨 출력
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
require("regenerator-runtime/runtime.js");
function asyncGeneratorStep/* Like __awaiter */
function _asyncToGenerator/* Yet another converter */
function fetchExample() {
return _fetchExample.apply(this, arguments);
}
function _fetchExample() {
_fetchExample = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
var r;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return fetch('https://example.com');
case 2:
r = _context.sent;
_context.next = 5;
return r.text();
case 5:
return _context.abrupt("return", _context.sent);
case 6:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return _fetchExample.apply(this, arguments);
}
Babel은 TypeScript와 마찬가지로
async-await
를 생각합니다. 몇 가지 추가 항목이 있는 생성기이므로 가져오기뿐만 아니라 일부 도우미 함수도 생성합니다.무엇을 할까요?
간단한 Promise 체인을 사용하십시오. 너무 "전통적"으로 보일 수 있지만 어떤 것으로도 잘 변환됩니다.
3. 반복 가능한 반복
여러 JS 구성으로 인해 반복자 반복이 발생합니다. for-of
루프, 반복 가능한 확산 및 반복 가능한 구조 해제.
그러나 이 기능에 대한 몇 가지 좋은 소식이 있습니다.
TypeScript: 컴파일러가 없으면
downlevelIteration
1) 배열 반복만 허용하고 2) 반복을 단순 인덱싱된 액세스로 변환합니다Babel: 컴파일러가 배열을 유추하는 경우 단순 인덱싱된 액세스를 사용합니다
그러나 이러한 소식이 코드에 적용되지 않으면 코드가 부풀려집니다 😐
입력
const iterable = (() => [1, 2])()
for (const i of iterable) {
console.log(i)
}
TypeScript 출력
var __values = /* ... */
var e_1, _a;
var iterable = (function () { return [1, 2]; })();
try {
for (var iterable_1 = __values(iterable), iterable_1_1 = iterable_1.next(); !iterable_1_1.done; iterable_1_1 = iterable_1.next()) {
var i = iterable_1_1.value;
console.log(i);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (iterable_1_1 && !iterable_1_1.done && (_a = iterable_1.return)) _a.call(iterable_1);
}
finally { if (e_1) throw e_1.error; }
}
iterable
가 생성기인 경우에는 special handling이 있습니다. 이 예제에서는 필요하지 않지만 컴파일러는 확신할 수 없습니다.바벨 출력
function _createForOfIteratorHelper/* ... */
function _unsupportedIterableToArray/* ... */
function _arrayLikeToArray/* ... */
var iterable = function () {
return [1, 2];
}();
var _iterator = _createForOfIteratorHelper(iterable),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var i = _step.value;
console.log(i);
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
TS와 마찬가지로 Babel은 실제로 이 예제에서 필요하지 않은 예외 경우를 처리합니다.
할 일
function forEach(iterable, effect) {
const itr = iterable[Symbol.iterator]()
for ( ; ; ) {
const n = itr.next()
if (n.done) {
return n.value
}
effect(n.value)
}
}
다른 블로터가 있습니까?
솔직히 ES6+ 기능은 추가 코드를 생성합니다. 그러나 내가 아는 한 생성된 코드는 위의 예만큼 크지 않습니다.
무엇을 할까요?
컴파일러가 생성하는 모든 것을 읽고 그것에 대해 무언가를 할 수 있는지 생각하십시오 🙂
my project의 dist
를 처음 봤을 때 충격을 받았습니다. 거의 모든 파일에 __read
또는 __whatever
가 있었고 모든 깔끔한 for-of
가 크고 보기 흉한 구조로 바뀌었습니다. 그러나 여기 및 에서 설명한 기술을 적용하여 번들 크기를 약 15% 줄였습니다. 당신도 할 수 있습니다! 😉
읽어주셔서 감사합니다. 다른 번들 블로터의 이름을 지정할 수 있습니까?
Reference
이 문제에 관하여(ES5 번들을 부풀리는 3가지 JavaScript 기능), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/alekseiberezkin/3-javascript-features-that-bloat-your-es5-bundle-3aoa
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(ES5 번들을 부풀리는 3가지 JavaScript 기능), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/alekseiberezkin/3-javascript-features-that-bloat-your-es5-bundle-3aoa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)