Spec-Zone.ru › Babel 7

Предположения компилятора

По умолчанию Babel пытается скомпилировать ваш код так, чтобы он максимально точно соответствовал поведению родного JavaScript. Однако это иногда означает генерацию большего объёма выходного кода или замедление его работы, просто чтобы поддерживать некоторые крайние случаи, которые вам могут не понадобиться.

Начиная с Babel 7.13.0, вы можете указать опцию assumptions в своей конфигурации, чтобы сообщить Babel, какие предположения можно сделать о вашем коде, чтобы лучше оптимизировать результат компиляции. Примечание: это заменяет различные опции loose в плагинах на опции верхнего уровня, которые могут применяться к нескольким плагинам (Ссылка на RFC).

Например:

{
  "targets": ">0.5%",
  "assumptions": {
    "noDocumentAll": true,
    "noClassCalls": true
  },
  "presets": ["@babel/preset-env"]
}

⚠ Это функция расширенного уровня. Будьте осторожны при включении предположений, поскольку они не соответствуют спецификации и могут привести к неожиданным ошибкам в вашем коде.

arrayLikeIsIterable​

При развёртывании или итерировании по массивоподобному объекту предположите, что он реализует метод [Symbol.iterator], с поведением, аналогичным методу родного JavaScript Array.prototype[Symbol.iterator], и, следовательно, непосредственно итерируется по элементам по индексу.

Это может быть полезно, например, для итерирования по коллекциям DOM в старых браузерах.

let images = $("img");

for (const img of images) {
  console.log(img);
}

const copy = [...images];

constantReexports​

При повторной экспорте привязки из модуля предположите, что она не изменяется, и поэтому безопасно её напрямую экспортировать, как если бы вы делали

import { value as val } from "dep";

export const value = val;

ПРИМЕЧАНИЕ: Это также влияет на плагины transform-modules-umd и transform-modules-amd.

export { value } from "dependency";

constantSuper​

Класс-родитель класса может быть изменён в любой момент с помощью Object.setPrototypeOf, что делает невозможным для Babel статически узнать его. При включении этой опции Babel предполагает, что он никогда не меняется, и, следовательно, всегда имеет значение, которое было помещено в extends предложение в объявлении класса.

class Child extends Base {
  method() {
    super.method(2);
  }
}

enumerableModuleMeta​

При компиляции ESM в CJS Babel определяет свойство __esModule в объекте module.exports. Предполагается, что вы никогда не итерируетесь по ключам module.exports или require("your-module") с помощью for..in или Object.keys, и, следовательно, безопасно определить __esModule как перечисляемое.

export const number = 2;

ignoreFunctionLength​

У функций есть свойство .length, которое отражает количество параметров до последнего не-по умолчанию параметра. При включении этой опции, предполагается, что скомпилированный код не зависит от свойства .length.

function fn(a, b = 2, c, d = 3) {
  return a + b + c + d;
}

ignoreToPrimitiveHint​

При использовании языковых функций, которые могут вызвать метод [Symbol.toPrimitive] объектов, предположите, что они не изменяют своего поведения в зависимости от параметра hint.

let str = `a${foo}b`;

iterableIsArray​

При использовании итерируемого объекта (в деструктуризации массивов, циклах for-of или развёртывании) предположите, что он является массивом.

const [first, ...rest] = obj;

call(first, ...obj);
let arr = [first, ...obj];

for (const el of obj) {
  console.log(el);
}

mutableTemplateObject​

Не используйте Object.freeze для объекта шаблона, созданного для меченых шаблонов строк. Это фактически означает использование помощника taggedTemplateLiteralLoose вместо taggedTemplateLiteral.

let str = tag`a`;

noClassCalls​

При преобразовании классов предполагайте, что они всегда создаются с new и никогда не вызываются как функции.

class Test {
  constructor() {
    this.x = 2;
  }
}

noDocumentAll​

При использовании операторов, проверяющих null или undefined, предполагайте, что они никогда не используются со специальным значением document.all.

let score = points ?? 0;
let name = user?.name;

noIncompleteNsImportDetection​

Предполагается, что за свойством модуля экспорта нет наблюдения до инициализации. Например, при попытке получить доступ к ns.foo, он вернёт undefined как с этой предпосылкой, так и без неё. Разница в том, что Object.prototype.hasOwnProperty.call(ns, "foo") вернёт false при noIncompleteNsImportDetection: true.

export var foo;

noNewArrows​

Предполагается, что код никогда не пытается создать стрелочные функции с использованием new, что запрещено спецификацией.

ПРИМЕЧАНИЕ: Это предположение по умолчанию true. Оно по умолчанию будет false начиная с Babel 8.

let getSum = (a, b) => {
  return { sum: a + b }
};

objectRestNoSymbols​

При использовании паттернов остатка в деструктуризации объектов предположите, что деструктурируемые объекты не имеют ключей символов или что это не проблема, если они не копируются.

let { name, ...attrs } = obj;

privateFieldsAsProperties​

Предполагайте, что «мягкая приватность» достаточна для приватных полей, и, следовательно, они могут храниться как публичные неперечисляемые свойства с уникальным именем (вместо использования внешнего WeakMap). Это упрощает отладку скомпилированных приватных полей.

class Foo {
  #method() {}

  #field = 2;

  run() {
    this.#method();
    this.#field++;
  }
}

⚠️ При использовании встроенных помощников Babel сгенерированные строковые ключи уникальны для каждого файла, а не глобально. Это может привести к конфликтам при расширении классов из разных файлов с приватными полями с одинаковым именем.

privateFieldsAsSymbols​

История
Версия Изменения
v7.21.0 Добавлено предположение privateFieldsAsSymbols

Предполагайте, что «мягкая приватность» достаточна для приватных полей, и, следовательно, они могут храниться как публичные свойства с ключом-символом (вместо использования внешнего WeakMap). Это упрощает отладку скомпилированных приватных полей.

class Foo {
  #method() {}

  #field = 2;

  run() {
    this.#method();
    this.#field++;
  }
}

pureGetters​

Предполагайте, что у геттеров, если они есть, нет побочных эффектов и к ним можно обращаться многократно.

let a = obj;

a.b?.();

setClassMethods​

При объявлении классов предполагайте, что методы не скрывают геттеры в суперклассе и что программа не зависит от того, являются ли методы неперечисляемыми. Таким образом, безопасно присваивать методы вместо использования Object.defineProperty.

class Foo extends Bar {
  method() {}

  static check() {}
}

setComputedProperties​

При использовании вычисляемых свойств объекта предполагайте, что объект не содержит свойств, которые перезаписывают установленные в том же объекте, и поэтому безопасно их присваивать, а не определять их с помощью Object.defineProperty.

let obj = {
  set name(value) {},
  [key]: val
}

setPublicClassFields​

При использовании публичных полей класса, предполагается, что они не перекрывают методы-геттеры в текущем классе, его подклассах или суперклассе. Таким образом, их можно безопасно присваивать вместо использования Object.defineProperty.

class Test {
  field = 2;

  static staticField = 3;
}

setSpreadProperties​

При использовании оператора spread для объектов, предполагается, что распакованные свойства не вызывают геттеры целевого объекта, и поэтому их можно безопасно присваивать, вместо того чтобы определять их с использованием Object.defineProperty.

const result = {
  set name(value) {},
  ...obj,
};

skipForOfIteratorClosing​

При использовании for-of с итератором, он всегда должен быть закрыт с помощью .return() и с помощью .throw() в случае ошибки. При использовании данного варианта Babel предполагает, что эти методы не определены или пусты, и избегает их вызова.

for (const val of iterable) {
  console.log(val);
}

superIsCallableConstructor​

При расширении классов, предполагается, что суперкласс является вызываемым. Это означает, что расширять встроенные классы или функции не получится, но только скомпилированные классы или ES5 function конструкторы.

class Child extends Parent {
  constructor() {
    super(42);
  }
}

© 2014-present Sebastian McKenzie
Licensed under the MIT License.
https://babeljs.io/docs/assumptions/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API