Давайте поговорим о Babel-runtime и Babel-polyfill в Babel 7.4.0.

Babel

Резюме: Новичков может смутить использование Babel, а также плохо понять настройку и разницу многих параметров. В этой статье будут использованы некоторыеbabel-runtimeиbabel-polyfillПростой пример, который поможет читателям различить и понять сценарии использования этих двух инструментов.

предисловие

Мы знаем, что Babel — это компилятор JS общего назначения, с помощью Babel мы можем компилировать код JS, написанный в соответствии с последним стандартом, в версию общего назначения, совместимую с различными браузерами или Node. Вы можете установить поPresets (пресеты, набор похожих плагинов)илиПлагиныСообщите Babel, как следует транспилировать код, например:@babel/preset-env(переводES6 ~ ES9синтаксис),@babel/preset-react(переводReact).

@babel/preset-env

вводить

Preset-env — это набор плагинов синтаксиса ES. Официально больше не рекомендуется использовать такие пакеты, как preset-201x. Этот пакет может быть автоматически совместим с кодом посредством настройки, включая автоматическое введение прокладок полифилла для работы с новыми API ( Например:Promise,Generator,Symbolи т. д.) и методы экземпляра (например,Array.prototype.includesЖдать).

использовать

  1. Создайте файл конфигурации .babelrc в корневом каталоге

     {
         "presets": [
             [ "@babel/preset-env", {
                 "targets": {},
                 "useBuiltIns": false,
                 "corejs": false
             }]
         ]
     }
    
    • target: Указывает, что нужно генерировать экологически безопасный код для проекта. Если вы не настроите его, babel будет избегать всех ES6+ для адаптации к среде, что крайне не рекомендуется.
    • useBuiltIns: этот параметр используется с @babel/polyfill дляBabel > 7.4.0, эта библиотека больше не рекомендуется официально, пожалуйста, выберитеcore-js, введите число 2 или 3 в параметре corejs в соответствии с установленной версией core-js.
  2. Установить@babel/preset-envа такжеcore-js

    исходный код

    const test = () => {
       `es8`.padStart(2)
    }
    

    Результаты перевода

    // useBuiltIns: false
    
    "use strict";
    
    var test = function test() {
       'es8'.padStart(2);
    };
    
    // useBuiltIns: "usage" 
    // corejs: 3
    
    "use strict";
    
    require("core-js/modules/es.string.pad-start");
    
    var test = function test() {
       'es8'.padStart(2);
    };
    

    Видно, что при использованииuseBuiltIns: false, Babel преобразует только стрелочную функцию, используяuseBuiltIns: usage, Babel динамически вводитcore-js/modules/es.string.pad-startдля глобального объекта.

Примечание:Мы знаем, что ES+ содержит не только новый синтаксис (например, стрелочные функции, классы), но также некоторые расширения экземпляров (Array.prototype.includes и т. д.) и множество встроенных функций (таких как Promise, Symbol). тем не мениеpreset-envВы ничего не можете сделать, чтобы справиться с этими сценариями приложений, не вводя полифиллы. Чтобы решить такую ​​проблему, у нас обычно есть два метода: использоватьPolyfillилиBabel-runtimeВыполнить заполнение функции. Далее мы приведем примеры, иллюстрирующие преимущества и недостатки обоих сценариев и сценариев применения.

@babel/polyfill

упомянутый ранееuseBuiltInsПредставлен простой пример обработки полифилла, а затем мы объединим несколько примеров, чтобы подробно понять использование полифилла. существуетBabel > 7.4.0Раньше обычно мы устанавливалиbabel-polyfillили@babel/polyfillДля обработки методов экземпляра и новых встроенных функций ES+, а после версии 7.4.0, когда мы решим установить@babel/polyfill, вы получите следующее предупреждение:

warning @babel/polyfill@7.4.4: � As of Babel 7.4.0, this
package has been deprecated in favor of directly
including core-js/stable (to polyfill ECMAScript
features) and regenerator-runtime/runtime
(needed to use transpiled generator functions):

  > import "core-js/stable";
  > import "regenerator-runtime/runtime";

Разве это не немного неловко ㄟ(▔,▔)ㄏ. Что это обозначает? По сути сам полифилл представляет собой набор стабильных версий core-js и regenerator-runtime, т.е.import @babel/polyfillЭквивалентно:

import 'core-js/stable';
import 'regenerator-runtime/runtime';

Таким образом, дляBabel >= 7.4.0случае, нам нужно установитьcore-jsальтернативаbabel-polyfillregenerator-runtimeбудет установлен в нашем@babel/runtimeОн устанавливается автоматически, поэтому вам не нужно устанавливать его отдельно.

Сотрудничайте с тем, как ввести прокладку из полифилла в соответствии сuseBuiltInsможно разделить на три типа, а именноentry, usageиfalse.

исходный код

/******* useBuiltIns: entry 时添加一下两行代码 ********/ 
import 'core-js/stable';
import 'regenerator-runtime/runtime';
/****************************************************/

const a = new Promise();
let b = new Map()

Результаты перевода

// 1. useBuiltIns: entry
"use strict";

require("core-js/modules/es.symbol");

require("core-js/modules/es.symbol.description");

require("core-js/modules/es.symbol.async-iterator");

// ..... 此处省略400个包

require("regenerator-runtime/runtime");

var a = new Promise();
var b = new Map();


// 2. useBuiltIns: usage
"use strict";

require("core-js/modules/es.array.iterator");

require("core-js/modules/es.map");

require("core-js/modules/es.object.to-string");

require("core-js/modules/es.promise");

require("core-js/modules/es.string.iterator");

require("core-js/modules/web.dom-collections.iterator");

var a = new Promise();
var b = new Map();

// 3. useBuiltIns: false
"use strict";

var a = new Promise();
var b = new Map();

Сравнивая три метода использования, мы можем обнаружить, что,falseВыполняется только преобразование синтаксиса,entryВведены все пакеты расширения es, нужны они или нет, они все запакованы, толькоusageОн автоматически обнаружит функции, используемые в коде, и автоматически введет модули (Примечание: Babel по умолчанию не обнаружит сторонний код зависимого пакета, поэтому используйтеusageКогда пакет кода, представленный третьей стороной, не внедряется в модуль, это может вызвать ошибку).

Итак, если вы не учитываете здесь размер пакета кода, вы можете выбратьentryСпособ. И если вам нужно, чтобы код был максимально компактным, используйтеusage, что также является официальным рекомендуемым использованием.

считать:На данный момент вы думаете, что проект использует полифилл, и написание кода уже может летать, ха-ха~. Затем давайте предположим сценарий приложения. Предположим, нам нужно выпустить библиотеку классов для использования другими. Мы используем полифилл, чтобы ввести встроенную функцию Promise. К сожалению, чужой локальный код также инкапсулирует функцию с именем Promise. Реальный Ли Куй встречает поддельный Ли Куй, ты говоришь, что не умрешь  ̄□ ̄. Так что для мира, здесь нам нужны наши@babel/runtimeПоявились чернила.

@babel/runtime

babel-runtime обычно используется в двух сценариях:

  • Разрабатывать библиотеки/инструменты классов (генерировать код, не загрязняющий глобальное пространство и встроенные прототипы объектов)
  • с помощью@babel/runtimeУдалите лишние служебные функции во вспомогательной функции.

Примечание:Мы должны часто видеть в другой документации и инструкциях по использованиюruntimeМетоды экземпляра не поддерживаются, даже в предыдущем использовании, либоBabel 7.0.0 ~ 7.4.0илиBabel < 7.0.0, ничего не может с этим поделать. Их можно настроить толькоcorejs(необязательный false | 2), чтобы решить, использовать лиbabel/runtime-corejsальтернативаcore-jsилиpolyfill(необязательно true | false), чтобы решить, вводить ли новые встроенные функции глобально, но на самом деле они принципиально не изменились,corejs: 2Практически эквивалентно версии до 7.0.0polyfill: true.

Особенности:Настоящие изменения приходятBabel 7.4.0После этого вы можете выбрать импорт@babel/runtime-corejs3,настраиватьcorejs: 3чтобы помочь вам реализовать поддержку методов экземпляра.

Далее мы основываемся наBabel 7.4.0Давайте рассмотрим несколько примеров:

элемент конфигурации

{
    "presets": [
        [
            "@babel/preset-env"
        ],
    ],
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            "corejs": false // 可选 false | 2 | 3
        }]
    ]
}

Исходный код - удалить резервные функции утилиты

class Person {}

Результаты перевода

// 移除plugins中runtime配置
"use strict";

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Person = function Person() {
  _classCallCheck(this, Person);
};


// 引入插件runtime
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));

var Person = function Person() {
  (0, _classCallCheck2["default"])(this, Person);
};

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

Исходный код - пример глобального загрязнения и методы экземпляра

const a = new Promise();
[1, 2, 3].includes(1)

Результаты перевода

// corejs: false
"use strict";

var a = new Promise();
[1, 2, 3].includes(1);

// corejs: 2
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");

var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));

var a = new _promise["default"]();
[1, 2, 3].includes(1);

// corejs: 3
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));

var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));

var _context;

var a = new _promise["default"]();
(0, _includes["default"])(_context = [1, 2, 3]).call(_context, 1);

Комбинируя код, мы видим, чтоcorejs: falseПо сути, это эквивалентно использованию@babel/polyfillвремяuseBuiltIns: false, преобразуется только синтаксис ES.corejs:2ЭквивалентноBabel 6времяpolyfill: true, они оба создают среду песочницы для кода,core-jsДайте псевдонимы, чтобы не загрязнять глобальное пространство.corejs: 3вcorejs: 2На основе метода он решает проблему, связанную с тем, что метод не может быть реализован раньше, и в то же время он также предотвращает загрязнение глобального пространства, что идеально ~

Суммировать

  1. Babel < 7.4.0
    • Чтобы разработать библиотеку классов, выберите @babel/runtime.
    • Внутренний проект, @babel/polyfill
  2. Babel >= 7.4.0, ничего не говори, иди прямо@babel/runtimeНу, потому что у тебя есть все, что ты хочешь