JavaScript — это язык, который развивается очень быстро, и иногда мы хотим использовать его новейшие функции, но, если наш браузер или среда не позволяют этого напрямую, нам придется транспилировать его, чтобы он мог это сделать.
Транспилирование — это преобразование исходного кода, написанного на одном языке, на другой язык с сопоставимым уровнем абстракции. Следовательно, в случае JavaScript транспилятор берет синтаксис, который старые браузеры не понимают, и превращает его в синтаксис, который они понимают.
Polyfilling vs. Transpiling
Оба метода работают с одной и той же целью: мы можем написать код, использующий новые функции, которые не реализованы в нашей целевой среде, а затем применить один из этих методов.
Полифил — это часть кода, в котором современные функции реализуются таким образом, чтобы их можно было применить для работы в старых версиях браузера.
Транспилирование — это сочетание двух слов: transforming — преобразование и compiling
— компиляция. Иногда новый синтаксис не может быть реализован с помощью полифилов, в таком случае мы используем транспилятор.
Представим, что мы используем старый браузер, который не поддерживает функцию Number.isNaN, представленную в спецификации ES6. Чтобы использовать эту функцию, нам нужно создать полифил для этого метода, но нам это понадобится только в том случае, если он еще не доступен в браузере.
Для этого мы создадим функцию, которая имитирует поведение функции isNaN и добавит её к свойству прототипа Number.
//Имитирует функцию isNaN
if (!Number.isNan) {//ещё не доступно.
Number.prototype.isNaN = function isNaN(n) {
return n !== n;
};
}
let myNumber = 100;
console.log(myNumber.isNaN(100));
Теперь мы собираемся транспилировать код для недавно созданной функции. Представим, что большинство браузеров не может выполнить эту функцию, и в этом случае мы не можем создать полифилл для имитации поведения. Мы хотим запустить следующий код в Internet Explorer 11, поэтому собираемся преобразовать его с помощью транспилятора:
class mySuperClass {
constructor(name) {
this.name = name;
}
hello() {
return "Hello:" +this.name;
}
}
const mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello());
//Hello Rick
Полученный код был перенесен с помощью онлайн-транспилятора Babel, и теперь мы можем выполнить его в Internet Explorer 11:
"use strict";
function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }
function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var mySuperClass = /*#__PURE__*/function () {
function mySuperClass(name) {
_classCallCheck(this, mySuperClass);
this.name = name;
}
_createClass(mySuperClass, [{
key: "hello",
value: function hello() {
return "Hello:" + this.name;
}
}]);
return mySuperClass;
}();
var mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello()); //Hello Rick
Один из самых распространенных транспиляторов для JavaScript — это Babel. Babel — это инструмент, который был создан для помощи в переносе кода между различными версиями JavaScript и может быть установлен через диспетчер пакетов Node (npm).
Babel стал стандартом для компиляции приложений ECMAScript в версию ECMAScript, которая работает в браузерах, не поддерживающих такие приложения. Babel может компилировать другие версии ECMAScript, такие как React JSX.
В следующих шагах мы увидим, как использовать Babel для транспиляции и выполнения предыдущего класса mySuperMethod на машине Linux с установленным старым Node.js. В других операционных системах, таких как Windows 10 или macOS, действия аналогичны.
Примечание. На вашем компьютере должен быть установлен Node.js. Npm добавлен как функция в установщик Node.js
1. Откройте командную строку и создайте каталог с именем babelExample:
/mkdir babelExample
/cd babelExample
2. Создайте проект npm и оставьте значения по умолчанию. Следующая команда создаст файл с именем package.json:
npm init
скриншот содержимого файла package.json после выполнения команды npm init
Здесь index.js (имя файла может быть другим) — это точка входа в наше приложение. Сюда мы собираемся поместить наш код javascript, поэтому создайте файл index.js и поместите в него следующий код:
class mySuperClass {
constructor(name) {
this.name = name;
}
hello() {
return "Hello:" +this.name;
}
}
const mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello());
//Hello Rick
3. Хотя мы и можем установить Babel CLI глобально, лучше делать это локально, проект за проектом. Следующая команда добавит каталог node_modules и изменит файл package.json, чтобы добавить зависимости Babel:
npm install -save-dev @babel/core @babel/cli
скриншот package.json с зависимостями babel
4. Добавьте файл конфигурации .babelrc в корневую папку проекта и включите плагины для преобразований ES2015+.
Примечание. В Babel каждый трансформатор — это плагин, который мы можем установить индивидуально. Каждый пресет представляет собой набор связанных плагинов. Используя пресеты, нам не нужно самостоятельно устанавливать и обновлять десятки плагинов.
Установите пресет для всех функций ES6 (содержит группу плагинов):
npm install @babel/preset-env --save-dev
скриншот package.json с зависимостью preset-env babel
Отредактируйте файл .babelrc и добавьте конфигурацию, которая включает преобразования для ES6.
Запишите в файл .babelrc следующий код:
{
"presets": ["@babel/preset-env"]
}
5. Использование
Примечание. Если вы используете Windows 10 PowerShell, будьте осторожны с кодированием файлов, поскольку при запуске Babel могут возникнуть ошибки синтаксического анализа. Желательно, чтобы файлы были в кодировке UTF-8.
вход: index.js
выход: папка out (здесь Babel оставит перенесённые файлы)
Непосредственно, выполнив следующую команду в консоли:
./node_modules/.bin/babel index.js -d out
С помощью сценария npm, добавляющего следующую строку в ваш файл package.json:
"build": "babel index.js -d out"
скриншот содержимого файла package.json после добавления скрипта сборки
Выполните следующую команду:
npm run build
В обоих случаях вы получаете в папке out файл (или файлы), транспилированные в готовый для работы в браузерах, которые не поддерживают синтаксис класса ES6, код:
"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var mySuperClass = /*#__PURE__*/function () {
function mySuperClass(name) {
_classCallCheck(this, mySuperClass);
this.name = name;
}
_createClass(mySuperClass, [{
key: "hello",
value: function hello() {
return "Hello:" + this.name;
}
}]);
return mySuperClass;
}();
var mySuperClassInstance = new mySuperClass("Rick");
console.log(mySuperClassInstance.hello());
Заключение
Язык JavaScript постоянно меняется, и, благодаря этим инструментам, мы можем писать код с новым синтаксисом и новыми функциями, которые еще не реализованы во всех версиях браузеров.
Надеюсь, вам понравилась эта статья. Эту и многие другие полезные статьи для начинающих Frontend-разработчиков я транслирую в Telegram-канале Frontend.school(), где также готовлю полезные викторины для проверки своих знаний. Обращаю внимание, что канал является исключительно хобби и желанием помочь и не несет для меня материальной выгоды.
CoolCmd
хм, нужно добавить себе в профиль: угадываю источник перевода по заголовку статей
eugeneugene Автор
а что нет так?)