BabelJS - Complementos de Babel
BabelJS es un compilador de JavaScript que cambia la sintaxis del código dado en función de los ajustes preestablecidos y complementos disponibles. El flujo de la compilación de babel consta de las siguientes 3 partes:
- parsing
- transforming
- printing
El código dado a babel se devuelve como está con solo la sintaxis cambiada. Ya hemos visto que se agregan ajustes preestablecidos al archivo .babelrc para compilar código de es6 a es5 o viceversa. Los ajustes preestablecidos no son más que un conjunto de complementos. Babel no cambiará nada si los ajustes preestablecidos o los detalles de los complementos no se proporcionan durante la compilación.
Analicemos ahora los siguientes complementos:
- transform-class-properties
- Transform-exponentiation-operator
- For-of
- reposo del objeto y esparcimiento
- async/await
Ahora, crearemos una configuración de proyecto y trabajaremos en algunos complementos, lo que proporcionará una comprensión clara de los requisitos de los complementos en babel.
mando
npm init
Tenemos que instalar los paquetes necesarios para babel: babel cli, babel core, babel-preset, etc.
Paquetes para babel 6
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Paquetes para babel 7
npm install @babel/cli @babel/core @babel/preset-env --save-dev
Cree un archivo js en su proyecto y escriba su código js.
Clases: propiedades de clase de transformación
Observe los códigos que se indican a continuación para este propósito:
Ejemplo
main.js
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname + "-" + this.lname;
}
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
En este momento, no hemos proporcionado ningún detalle preestablecido o de complemento a babel. Si transpilamos el código usando el comando -
npx babel main.js --out-file main_out.js
main_out.js
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname + "-" + this.lname;
}
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
Obtendremos el código tal como está. Agreguemos ahora preset a.babelrc archivo.
Note - Crear .babelrc archivo dentro de la carpeta raíz de su proyecto.
.babelrc for babel 6
.babelrc for babel 7
{
"presets":["@babel/env"]
}
Ya hemos instalado los presets; ahora ejecutemos el comando nuevamente -
npx babel main.js --out-file main_out.js
main_out.js
"use strict";
var _createClass = 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);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Person = function () {
function Person(fname, lname, age, address) {
_classCallCheck(this, Person);
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
_createClass(Person, [{
key: "fullname",
get: function get() {
return this.fname + "-" + this.lname;
}
}]);
return Person;
}();
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
En ES6, la sintaxis de la clase es la siguiente
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname + "-" + this.lname;
}
}
Hay constructor y todas las propiedades de la clase están definidas dentro de él. En caso de que necesitemos definir propiedades de clase fuera de la clase, no podemos hacerlo.
Ejemplo
class Person {
name = "Siya Kapoor";
fullname = () => {
return this.name;
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
Si compilamos el código anterior, arrojará un error en babel. Esto da como resultado que el código no se compile.
Para que esto funcione de la manera que queremos, podemos hacer uso del complemento de babel llamado babel-plugin-transform-class-properties. Para que funcione, primero debemos instalarlo de la siguiente manera:
Paquetes para babel 6
npm install --save-dev babel-plugin-transform-class-properties
Paquete para babel 7
npm install --save-dev @babel/plugin-proposal-class-properties
Add the plugin to .babelrc file for babel 6 -
.babelrc for babel 7
{
"plugins": ["@babel/plugin-proposal-class-properties"]
}
Ahora, ejecutaremos el comando nuevamente.
mando
npx babel main.js --out-file main_out.js
main.js
class Person {
name = "Siya Kapoor";
fullname = () => {
return this.name;
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
Compiled to main_out.js
class Person {
constructor() {
this.name = "Siya Kapoor";
this.fullname = () => {
return this.name;
};
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
Output
A continuación se muestra el resultado que obtenemos cuando se usa en un navegador:
Operador de exponenciación - operador de exponenciación de transformación
** es el operador utilizado para exponenciación en ES7. El siguiente ejemplo muestra el funcionamiento del mismo en ES7. También muestra cómo transpilar código usando babeljs.
Ejemplo
let sqr = 9 ** 2;
console.log("%c"+sqr, "font-size:25px;color:red;");
Para transpilar el operador de exponenciación, necesitamos instalar un complemento de la siguiente manera:
Packages for babel 6
npm install --save-dev babel-plugin-transform-exponentiation-operator
Packages for babel 7
npm install --save-dev @babel/plugin-transform-exponentiation-operator
Agregue los detalles del complemento a .babelrc archivo de la siguiente manera para babel 6 -
{
"plugins": ["transform-exponentiation-operator"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-exponentiation-operator"]
}
command
npx babel exponeniation.js --out-file exponeniation_out.js
exponeniation_out.js
let sqr = Math.pow(9, 2);
console.log("%c" + sqr, "font-size:25px;color:red;");
Output
Para-de
Los paquetes necesarios para los complementos en babel6 y 7 son los siguientes:
Babel6
npm install --save-dev babel-plugin-transform-es2015-for-of
Babel 7
npm install --save-dev @babel/plugin-transform-for-of
.babelrc for babel6
{
"plugins": ["transform-es2015-for-of"]
}
.babelrc for babel7
{
"plugins": ["@babel/plugin-transform-for-of"]
}
forof.js
let foo = ["PHP", "C++", "Mysql", "JAVA"];
for (var i of foo) {
console.log(i);
}
mando
npx babel forof.js --out-file forof_es5.js
Forof_es5.js
let foo = ["PHP", "C++", "Mysql", "JAVA"];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = foo[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var i = _step.value;
console.log(i);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
Output
objeto resto propagación
Los paquetes necesarios para los complementos en babel6 y 7 son los siguientes:
Babel 6
npm install --save-dev babel-plugin-transform-object-rest-spread
Babel 7
npm install --save-dev @babel/plugin-proposal-object-rest-spread
.babelrc for babel6
{
"plugins": ["transform-object-rest-spread"]
}
.babelrc for babel7
{
"plugins": ["@babel/plugin-proposal-object-rest-spread"]
}
o.js
let { x1, y1, ...z1 } = { x1: 11, y1: 12, a: 23, b: 24 };
console.log(x1);
console.log(y1);
console.log(z1);
let n = { x1, y1, ...z1};
console.log(n);
mando
npx babel o.js --out-file o_es5.js
o_es5.js
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i]; for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
let _x1$y1$a$b = { x1: 11, y1: 12, a: 23, b: 24 },
{ x1, y1 } = _x1$y1$a$b,
z1 = _objectWithoutProperties(_x1$y1$a$b, ["x1", "y1"]);
console.log(x1);
console.log(y1);
console.log(z1);
let n = _extends({ x1, y1 }, z1);
console.log(n);
Output
async / await
Necesitamos que se instalen los siguientes paquetes para babel 6:
npm install --save-dev babel-plugin-transform-async-to-generator
Paquetes para babel 7
npm install --save-dev @babel/plugin-transform-async-to-generator
.babelrc for babel 6
{
"plugins": ["transform-async-to-generator"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-async-to-generator"]
}
async.js
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
mando
npx babel async.js --out-file async_es5.js
async_es5.js
function _asyncToGenerator(fn) {
return function () {
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
} if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then(function (value) {
step("next", value);
},
function (err) {
step("throw", err); });
}
} return step("next");
});
};
}
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = (() => {
var _ref = _asyncToGenerator(function* () {
let msg = yield timer();
console.log(msg);
console.log("hello after await");
});
return function out() {
return _ref.apply(this, arguments);
};
})();
out();
Tenemos que hacer uso de polyfill para lo mismo, ya que no funcionará en navegadores donde las promesas no sean compatibles.
Output