NodeJS, Express y ES6
Tags: node, express
Published: 2023-03-21 02:01:16

Publicado originalmente (2021-01-11) en mi [sitio web.](https://diniremix.web.app)


Configurando **Express** para utilizar **ES6** con **nodeJS** y no morir en el intento.

&nbsp;
**TL;DR**

ECMAScript 2015 ó ES2015 es una importante actualización del lenguaje de programación **JavaScript**.

Es la primera actualización importante del lenguaje desde ES5, que se estandarizó en 2009.
Por lo tanto, ES2015 suele llamarse **ES6**.

ES6 permite entre otras cosas:

- **let** -> declarar variables con alcance de bloque utilizando la palabra clave **let** y las diferencias entre **let** y **var**.
- **const** -> definir constantes, usando la palabra clave **const**.
- Establecer el valor por defecto de los parámetros de una función.
- Operador de propagación **(...)**.
- **for...of** -> para iterar sobre los elementos de un objeto iterable.
- **Template literals** -> **(` `)**.
- Módulos de ES6(lo que nos compete principalmete en esta entrada) :smile:
- y un [largo etc...](http://es6-features.org/#Constants)


&nbsp;

## Comenzando

Para este tutorial necesitamos:

- [nodeJS](https://nodejs.org/es/download/) versión 12.x
- [npm](https://www.npmjs.com/) versión 6.x ó superior

Creando los archivos necesarios.

```bash
$ mkdir -pv express-es6/src
```

```bash
$ cd express-es6
$ touch package.json .babelrc .prettierrc src/server.js
```

La estructura del proyecto deberá lucir como:

```
├── .babelrc
├── .prettierrc
├── package.json
└── src
    └── server.js
```


En el archivo **.prettierrc** agregamos lo siguiente:

```js
{
  "singleQuote": false,
  "printWidth": 80,
  "trailingComma": "es5",
  "arrowParens": "always",
  "bracketSpacing": false,
  "jsxBracketSameLine": false,
  "parser": "babel",
  "semi": true,
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve",
  "useTabs": true,
  "tabWidth": 4,
  "endOfLine": "lf"
}
```

Para más info consulta: [Prettier Configuration File](https://prettier.io/docs/en/configuration.html)

&nbsp;

En el archivo **.babelrc** agregamos lo siguiente:

```js
{
    "presets": [
        ["@babel/preset-env",{
            "targets": {
                // specify supported browsers (ES2015+ Features to transpile)
                "node": "current"
            },
            // no module transpilation to CJS (!important)
            "modules": false
        }]

    ],
    "plugins": [
        ["babel-plugin-module-resolver",
            {
                "root": ["."],
                "extensions": [".js"],
            	// some alias
                "alias":
                {
                    "@middlewares": "./src/middlewares",
                    "@modules": "./src/modules",
                    "@routes": "./src/routes"
                }
            }
        ],
        [
            "@babel/plugin-transform-modules-commonjs",
            {
                "allowTopLevelThis": true
            }
        ],
        [
            "@babel/plugin-transform-runtime",
            {
                "regenerator": true
            }
        ]
    ]
}
```

> El en apartado de referencias, al final del post, se encuentran enlaces para continuar la lectura, acerca de la configuración para Babel.


&nbsp;
En el archivo **package.json** agregamos lo siguiente:

```js
{
  ...
  "engines": {
    "node": ">=12.0.0"
  },
  "dependencies": {
    "express": "^4.17.1",
    "module-alias": "^2.2.2"
  },
  "devDependencies": {
    "rimraf": "^3.0.2",
    "@babel/cli": "^7.13.14",
    "@babel/core": "^7.13.14",
    "@babel/node": "^7.13.13",
    "@babel/plugin-transform-runtime": "^7.13.10",
    "@babel/preset-env": "^7.13.12",
    "babel-plugin-module-resolver": "^4.1.0",
    "prettier": "^2.2.1"
  }
}
```

&nbsp;
## Instalando las depedencias

```bash
npm install
```

&nbsp;
## Utilizando ES6

Ingresamos al directorio **src** y editamos el archivo **server.js**

```js
import express from "express";
let server = express();

const port = process.env.PORT || 8080;
const api = "/api";
const version = 0.1;

server.use(function (req, res, next) {
	res.header("Content-Type", "application/json");
	next();
});

server.get("/", async (req, res) => {
	res.status(200).json({
		status: "OK",
		message: `welcome to Server, use ${api} instead`,
	});
});

server.get(api, async (req, res) => {
	res.status(200).json({
		status: "OK",
		message: `Welcome to Server, version: ${version}`,
	});
});

server.get("*", async (req, res) => {
	res.status(404).json({
		status: "Fail",
		message: "Not Found",
	});
});

server.listen(port, function () {
	console.log("server app listening on port:", port);
	console.log("version:", version);
});
```

&nbsp;
## Finalizando

Ahora agregamos unas tareas al **package.json** para facilitar las cosas.

```js
{
  ...

  "scripts": {
    "clean": "rimraf dist",
    "build": "babel src -d dist",
    "dev": "NODE_ENV=development babel-node src/server.js",
    "serve": "NODE_ENV=production node dist/server.js",
    "start": "node server.js",
    "lint": "prettier --config .prettierrc --check \"src/**/*.js\"",
    "lint:fix": "prettier --config .prettierrc --check \"src/**/*.js\" --write"
  },
}
```


&nbsp;
## Pruebas

Iniciando el servidor...

```bash
$ npm run dev

> ServerWithES6@0.0.1 dev /Users/diniremix/Develop/express-es6
> NODE_ENV=development babel-node src/server.js

server app listening on port: 8080
version: 0.1
```

curl es tu amigo....

```bash
$ curl --request GET \
  --url http://localhost:8080/api \
  --header 'Content-Type: application/json'

{"status":"OK","message":"Welcome to Server, version: 0.1"}%
```


Construyendo...
```bash
$ npm run build

> ServerWithES6@0.0.1 build /Users/diniremix/Develop/express-es6
> babel src -d dist

Successfully compiled 1 file with Babel (527ms).
```


Chequeando el código con prettier...
```bash
$ npm run lint

> ServerWithES6@0.0.1 lint /Users/diniremix/Develop/express-es6
> prettier --config .prettierrc --check "src/**/*.js"

Checking formatting...
[warn] jsxBracketSameLine is deprecated.
All matched files use Prettier code style!
```


Corrigiendo posibles inconsistencias con prettier...
```bash
$ npm run lint:fix

> ServerWithES6@0.0.1 lint:fix /Users/diniremix/Develop/express-es6
> prettier --config .prettierrc --check "src/**/*.js" --write

Checking formatting...
[warn] jsxBracketSameLine is deprecated.
All matched files use Prettier code style!
```


&nbsp;
Todo lo necesario, [en este snippet.](https://gitlab.com/-/snippets/2177469)

Todo esto hace parte de la configuración de [Knot](https://gitlab.com/HomeInside/Knot), un Proyecto de **HomeInside**, para construir APIs RESTful y microservicios usando Node.js, Express y Firestore.


&nbsp;
## Referencias

 - [Knot](https://gitlab.com/HomeInside/Knot)
 - [Módulos JavaScript](https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Modules)
 - [javascripttutorial](https://www.javascripttutorial.net/es6/)
 - [ECMAScript 6 — New Features: Overview & Comparison](http://es6-features.org)
 - [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env)
 - [@babel/plugin-transform-runtime](https://babeljs.io/docs/en/babel-plugin-transform-runtime)
 - [babel-plugin-module-resolver](https://github.com/tleunen/babel-plugin-module-resolver#readme)
 - [codesquery/nodejs-restapi](https://github.com/codesquery/nodejs-restapi)
 - [KunalKapadia/express-mongoose-es6-rest-api](https://github.com/KunalKapadia/express-mongoose-es6-rest-api)