Резюме: Новичков может смутить использование 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
Ждать).
использовать
-
Создайте файл конфигурации .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.
-
Установить
@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-polyfill
,иregenerator-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
На основе метода он решает проблему, связанную с тем, что метод не может быть реализован раньше, и в то же время он также предотвращает загрязнение глобального пространства, что идеально ~
Суммировать
-
Babel < 7.4.0
- Чтобы разработать библиотеку классов, выберите @babel/runtime.
- Внутренний проект, @babel/polyfill
-
Babel >= 7.4.0
, ничего не говори, иди прямо@babel/runtime
Ну, потому что у тебя есть все, что ты хочешь