Краткое руководство по Babel

JavaScript

Когда я впервые начал использовать babel, я полагал, что многие студенты должны быть такими же, как я, с небольшим пониманием использования и настройки babel, связанных с babel пакетов @babel/core, @babel/cli, babel-loader, @babel /polyfill, @babel/plugin -transform-runtime, когда будет введен @babel/runtime и какова роль и разница, будет запутано. Цель этой статьи — помочь учащимся, которые еще не использовали или только что использовали Babel, быстро разобраться в этом содержании и с легкостью использовать Babel как мощный инструмент.
Рекомендуемая официальная документация для тех, кто хочет узнать больше о babel:китайский язык,английский.

Примечание. В этой статье используются версии babel 7 и webpack версии 4. Существуют различия в установке и настройке разных версий.

что такое бабель

Babel — это компилятор Javascript и один из наиболее часто используемых инструментов для фронтенд-разработки.Он в основном используется для преобразования кода версии ECMAScript 2015+ в обратно совместимый синтаксис JavaScript, чтобы он мог работать в текущих и старых версиях браузеров или других средах. . Например, в коде используется стрелочная функция ES6. Такой способ написания сообщит об ошибке в IE. Чтобы код работал в IE, код должен быть скомпилирован в способ написания, поддерживаемый IE. это работа Вавилона.

const fn = arg => {
    console.log(arg);
};

//babel转换后

"use strict";

var fn = function fn(arg) {
  console.log(arg);
};

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

  1. Используйте инструмент командной строки
// 在项目中执行
npm i @babel/core @babel-cli -D

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

{
  "scripts": {
    "build": "babel src -d dist"
  }, 
}

Затем выполните npm run build в командной строке, и babel скомпилирует файлы в папке src и выведет их в папку dist.

  1. используется в вебпаке

По сравнению с использованием команд командной строки напрямую, наши проекты теперь обычно используют инструменты упаковки.Если мы сможем комбинировать babel с инструментами упаковки, будет удобнее автоматически вызывать babel для компиляции кода при упаковке. Возьмем в качестве примера webpack.Если вы хотите использовать функцию компиляции babel в webpack, вам нужно установить babel-loader.

npm i @babel/core babel-loader -D

Затем в файле конфигурации веб-пакета настройте babel-loader для загрузки и обработки файлов js.

// webpack.config.js
const path = require('path');
module.exports = {
    entry: './src/app.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js'
    },
    module: {
        rules: [
            { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }
        ]
    }
};
  1. Больше способов использования

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

Примечание: @babel/core — это базовый пакет версии babel7, и его необходимо ввести.

настроить

Метод использования очень прост, но этого недостаточно.Теперь выполните компиляцию babel, и вы обнаружите, что компиляция прошла успешно, но содержимое после компиляции ничем не отличается от до компиляции, это потому, что мы не сказали babel как компилировать и что компилировать. , нам нужен файл конфигурации, чтобы сообщить Babel, как работать.
Существует несколько способов настройки файла:

  1. Установите поле babel в package.json.
  2. Файл .babelrc или .babelrc.js
  3. файл babel.config.js

Для первого метода не нужно создавать файл, просто добавьте информацию о конфигурации babel в package.json.

//package.json
{
   "name":"babel-test",
   "version":"1.0.0",
   "devDependencies": {
       "@babel/core":"^7.4.5",
       "@babel/cli":"^7.4.4",
       "@babel/preset-env":"^7.4.5"
   }
   "babel": {
       "presets": ["@babel/preset-env"]
   }
}

Второй .babelrc и .babelrc.js — это один и тот же метод настройки, но формат файла отличается: один — это файл json, а другой — файл js.

.babelrc

{
    "presets": ["@babel/preset-env"]
}

.babelrc.js

//webpack的配置文件也是这种写法
module.exports = {
    presets: ['@babel/preset-env']
};

Эти два файла конфигурации предназначены для папок, то есть папка, в которой находится файл конфигурации, включая подпапки, будет применять настройки этого файла конфигурации, а файл конфигурации нижнего уровня перезапишет файл конфигурации верхнего уровня. Таким образом, разные каталоги могут быть назначены разным каталогам.Настройте разные правила.
Третий тип babel.config.js записывается так же, как и .babelrc.js, но babel.config.js предназначен для всего проекта, а в корневую директорию проекта помещается только один проект.

Примечание 1: Файл .babelrc размещается в корневом каталоге проекта и имеет тот же эффект, что и babel.config.js.Если существуют оба типа файлов конфигурации, .babelrc перезапишет конфигурацию babel.config.js.

Примечание 2: Написать конфигурацию, в которой Package.json или создание профиля не имеет значения, чтобы увидеть личные привычки. Реагируйте на настройку проекта React Babel Project Project Create App Create-App создают в Package.json внутри, в то время как Vue Vue Официальные проектные леса @ Vue / CLI, созданные babel.config.js.

Плагины и пресеты

С файлом конфигурации следующим шагом будет указание Babel, что компилировать через файл конфигурации, а затем ввести соответствующие подключаемые модули компиляции (плагины).Например, преобразование функции стрелки, упомянутой выше, требует@babel/plugin-transform-arrow-functionsЭтот плагин, этот пакет мы устанавливаем через npm и задаем в конфигурации.

npm i @babel/plugin-transform-arrow-functions -D
// babel.config.js
module.exports = {
    plugins: ['@babel/plugin-transform-arrow-functions']
};

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

Пресет на самом деле представляет собой список предустановленных плагинов. Использование пресета означает установку и использование всех плагинов, указанных в пресете, таких как пресеты.@babel/preset-es2015, этот пресет включает @babel/plugin-transform-arrow-functions и другие плагины преобразования для новых функций es2015, таких как for-of, class, строки шаблона и т. д. Нам нужно только установить этот предустановленный пакет через npm и настроить его следующим образом, и мы можем использовать эти новые функции es2015 в нашем коде по желанию.При компиляции Babel преобразует эти коды в браузеры с низкой версией и распознает совместимые. .

npm i @babel/preset-es2015 -D
// babel.config.js
module.exports = {
    presets: ['@babel/preset-es2015']
};

Примечание: Babel не только поддерживает преобразование новых синтаксических функций, синтаксис react, vue преобразуется babel, например, реактивные проекты могут использовать предустановленную реакцию.

preset-env

Несмотря на то, что пресет значительно облегчил нам использование, если мы все еще хотим использовать обновленный синтаксис, такой как ** es2016 (эквивалент pow()), async/await es2017 и т. д., мы введем @babel/preset -es2016, @ babel/preset-es2017 и подобные, а по мере обновления синтаксиса js этих пресетов будет становиться все больше и больше. Итак, babel запустил предустановку babel-env, которая является умной предустановкой.Пока эта предустановка установлена, она автоматически преобразует новые функции в коде в код, поддерживаемый целевым браузером, в соответствии с установленным вами целевым браузером.

Взяв в качестве примера функцию стрелки преобразования, npm установите @babel/preset-env и настройте ее.

npm i @babel/preset-env -D
// babel.config.js
module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                targets: {
                    chrome: '58'
                }
            }
        ]
    ]
};

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

Подробнее о том, как установить целевую версию браузера, см.browserslist, Поддержка функции браузера по запросуcaniuse.

Примечание 1: Даже если цели не установлены, будет значение по умолчанию, правила > 0,5%, последние 2 версии, Firefox ESR, не мертв.
Примечание 2: Официальная рекомендация — использовать предустановленную среду.

плагин-преобразование-время выполнения и время выполнения

Когда я компилирую с помощью babel, некоторым функциям нужны некоторые инструментальные функции для помощи в реализации, такие как компиляция классов.

class People{
}

// babel编译后
'use strict';

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

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

В скомпилированном коде _classCallCheck — это инструментальная функция, реализованная вспомогательными функциями. Если классы используются в нескольких файлах, каждый файл будет генерировать инструментальную функцию после компиляции, что в конечном итоге приведет к созданию большого количества повторяющегося кода, что увеличит размер файла. Среда выполнения plugin-transform предназначена для решения этой проблемы, этот плагин преобразует эти функции инструмента в импортированную форму.

npm i @babel/plugin-transform-runtime -D
module.exports = {
    presets: ['@babel/preset-env'],
    plugins: ['@babel/plugin-transform-runtime']
};

После завершения установки и настройки используйте babel для компиляции результата следующим образом:

"use strict";

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

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

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

Функция инструмента _classCallCheck2 была импортирована из пакета npm, поэтому отдельный код функции инструмента генерироваться не будет. Но вы можете видеть, что функция инструмента импортирована из пакета @babel/runtime, поэтому вам необходимо установить пакет зависимостей @babel/runtime, чтобы при упаковке проекта не сообщалось об ошибке.

npm i @babel/runtime

Примечание: babel/runtime — это не зависимость разработки, а зависимость производства проекта. Среда выполнения plugin-transform используется при компиляции, а ваш проект зависит от babel/runtime, поэтому эти две вещи используются вместе.

babel-polyfill

Babel может трансформировать некоторые новые функции, но для новых встроенных функций (Promise, Set, Map), статических методов (Array.from, Object.assign), методов экземпляра (Array.prototype.includes) требуется, чтобы babel-polyfill был решен. , babel-polyfill полностью имитирует среду ES2015+.

Например, в вашем коде используется Array.from, но целевой браузер не поддерживает Array.from. Введение babel-polyfill добавит метод from в Array. Array.from, используемый при выполнении кода, фактически моделируется функцией babel-polyfill, хотя она и загрязняет статические методы Array, она обеспечивает совместимость. Предыдущее использование состояло в том, чтобы установить @babel/polyfill на npm и добавить пакет @babel/polyfill в точку входа в проект.

npm i @babel/polyfill
// entry.js
import "@babel/polyfill";

Однако этот метод был заброшен и не рекомендуется, поскольку @babel/polyfill относительно велик, общее введение не только увеличивает размер проекта, но и загрязняет слишком много переменных, поэтому рекомендуется использовать предустановленную среду вводить полифиллы по запросу.

// babel.config.js
module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                useBuiltIns: 'usage', // usage-按需引入 entry-入口引入(整体引入) false-不引入polyfill
                corejs: 2  // 2-corejs@2  3-corejs@3
            }
        ]
    ]
};

corejs – это библиотека, предоставляющая интерфейсы для браузеров с низкими версиями, а также являющаяся ядром функции полифилла. Здесь указана версия, которая вводит corejs. Вам необходимо установить указанную версию библиотеки corejs через npm в качестве производственной зависимости. .

npm i core-js@2

После выполнения компиляции babel вы можете увидеть следующие эффекты:

const a = Array.from([1])

//babel编译后
"use strict";

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

require("core-js/modules/es6.array.from");

var a = Array.from([1]); 

Видно, что перед использованием Array.from соответствующие полифилы были введены заранее из core-js, по названиям файлов можно, наверное, догадаться, каковы их функции.

Обсуждение плагина-преобразования-временной среды и Babel-Polyfill

Как упоминалось выше, plugin-transform-runtime в основном отвечает за преобразование функций инструментов в импортированные методы для сокращения повторяющегося кода, а babel-polyfill — за добавление связанных файлов для имитации совместимой среды. Одна проблема с babel-polyfill заключается в том, что добавление файлов загрязняет переменные Фактически, plugin-transform-runtime также предоставляет полифилл времени выполнения.
Мы изменим файл конфигурации.

module.exports = {
    plugins: [['@babel/plugin-transform-runtime', { corejs: 2 }]]
};

Здесь corejs отличается от corejs, установленного в пресетах. Corejs в этом месте указывает версию, называемую библиотекой runtime-corejs. При ее использовании также необходимо установить соответствующий пакет с npm.

npm i @babel/runtime-corejs2

Затем выполните компиляцию babel, чтобы увидеть разницу.

const a = Array.from([1])

//babel编译后
"use strict";

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

var _from = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/from"));

var a = (0, _from["default"])([1]);

Видно, что разница между этим методом и использованием babel-polyfill заключается в том, что Array.from не изменяется, но создается _from для имитации функции Array.from, вызов Array.from будет скомпилирован в вызов _from, поэтому Преимущество этого, очевидно, заключается в том, что он не загрязняет статический метод из массива.Все полифиллы в форме времени выполнения, предоставляемые средой выполнения plugin-transform-runtime, находятся в этой форме.

После моих тестов, в дополнение к методам прототипа, таким как Array.prototype.includes, другие встроенные функции (Promise, Set, Map) и статические методы (Array.from, Object.assign), упомянутые ранее, могут использовать плагины. форма -transform-runtime.

Тогда я подумал, поскольку эта форма не будет загрязнить переменные, то, конечно, его можно использовать, но после того, как спросить в группе, большие парни дали мнению (благодаря Большим парням Джаджаваку и Сяоге за их объяснения).

Среда выполнения не загрязняет глобальные переменные, но это может привести к дублированию кода в нескольких файлах.
При написании библиотек классов используется среда выполнения, а системные проекты по-прежнему используют полифилл.
Безопаснее всего использовать среду выполнения для написания библиотеки.Если мы используем include, но наша зависимая библиотека B также определяет эту функцию, то у нас возникнет проблема, когда мы введем полифилл глобально: перезаписать включения зависимой библиотеки B. Если использование среды выполнения безопасно, по умолчанию будет создана песочница. В этом случае особенно очевиден Promise. Многие библиотеки будут полагаться на bluebird или другие реализации Promise. Как правило, при написании библиотек не следует предоставлять какую-либо схему полифилла, но используйте Руководство объясняет, какие новые функции используются, что позволяет пользователям полифиллировать себя.

Уже ясно, какую форму использовать, зависит от типа проекта, но обычно для общих бизнес-проектов это функция инструмента обработки plugin-transform-runtime, которая совместима с обработкой babel-polyfill.

окончательное резюме

Имена пакетов Функция иллюстрировать
@babel/core babel компилирует основной пакет Требуемые зависимости разработки
@babel/cli Командная строка запускает командный инструмент babel. Не обязательно устанавливать зависимости для разработки, если в скрипте packages.json используется команда babel, ее необходимо установить.
babel-loader Используйте babel для загрузки файлов в webpack Не требуется устанавливать зависимости разработки, используемые в проектах веб-пакетов.
@babel/plugin-* Плагин реализации функции компиляции babel Зависимости разработки, установка в соответствии с требуемыми функциями
@babel/preset-* Пресеты плагинов реализации функций Зависимости разработки, установите в соответствии с требуемыми функциями, и рекомендуется использовать предустановленную среду для преобразования новых функций языка js.
@babel/plugin-transform-runtime Повторное использование служебных функций Нет необходимости устанавливать зависимости разработки, и он существует одновременно с @babel/runtime.
@babel/runtime Библиотека функций инструмента Нет необходимости устанавливать производственные зависимости, и он существует одновременно с @babel/plugin-transform-runtime.
@babel/polyfill Библиотека совместимости браузера более ранней версии Производственные зависимости устанавливать не обязательно и больше не рекомендуется.Рекомендуется импортировать по требованию через свойство useBuiltIns файла preset-env.
core-js@* Библиотека совместимости браузера более ранней версии Не обязательно устанавливать продакшн-зависимости, для внедрения полифилла через preset-env нужно установить этот пакет и указать версию через corejs
@babel/runtime-corejs* Совместимая с браузером библиотека с низкой версией, которая не загрязняет переменные Нет необходимости устанавливать производственные зависимости.После того, как параметр plugin-transform-runtime включен, полифиллы могут быть введены без загрязнения переменных.

Это в основном соответствующий контент, используемый babel.Что касается внутреннего принципа реализации компиляции babel, вы можете изучить его подробно.Вы также можете написать несколько плагинов и пресетов babel и опубликовать их на npm для всех, чтобы использовать.Я надеюсь, что вы можете понять эту статью после прочтения этой статьи и использование babel немного помогло.

Способность общая, уровень ограничен, приглашаю всех исправить и обсудить.