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