JavaScript es sin duda uno de los lenguajes de programación más populares que existen en la actualidad, y por una buena razón. Se puede ejecutar fácilmente en su navegador, en un servidor, en su escritorio o incluso en su teléfono como una aplicación. Una de las maneras más fáciles y más populares para escribir JavaScript está usando Node.js .
Existen bastantes recursos para aprender Node.js, pero no muchos de ellos realmente le brindan los antecedentes, las herramientas y los recursos que necesita para tener éxito en la escritura de código de Node.
Entonces, lo que pretendo hacer aquí es brindarles una guía que me hubiera gustado tener al comenzar. Comenzaré con una breve descripción de lo que realmente es Node y lo que hace detrás de la cortina, luego te daré algunos ejemplos concretos que puedes probar tú mismo en el navegador, y finalmente te daré un montón de recursos para guiarlo a través de algunos ejemplos / conceptos más útiles y prácticos.
Tenga en cuenta que esta guía no le enseñará cómo codificar, sino que lo guiará a través de los conceptos básicos del tiempo de ejecución de Node y npm.
Que es Node
Contenido
Node es un entorno de tiempo de ejecución multiplataforma del lado del servidor que se ejecuta en el motor JavaScript V8 , que impulsa el navegador Chrome de Google. Este es realmente el corazón de Node y es el componente que realmente analiza y ejecuta el código.
El motor V8 hace esto compilando JavaScript en código de máquina nativo, lo que lo hace mucho más rápido que un intérprete. Para acelerar aún más las cosas, el código compilado se optimiza (y se vuelve a optimizar) dinámicamente en tiempo de ejecución en función de la heurística del perfil de ejecución del código. Esto significa que a medida que se ejecuta el programa, el motor realiza un seguimiento de su rendimiento y acelera el código en función de ciertos factores que se controlan.
Como tiempo de ejecución, el gran enfoque de Node es utilizar un modelo de E / S sin bloqueo controlado por eventos para hacerlo ligero y rápido. Para algunos, este modelo de programación puede ser un poco confuso al principio, pero en realidad hace un gran trabajo al simplificar el desarrollo para aplicaciones de E / S pesadas, como sitios web.
Este diseño es ideal para optimizar el rendimiento y la escalabilidad de su código, que es una de las principales razones por las que se ha vuelto tan popular. Por ejemplo, alguien consiguió que manejara 600.000 conexiones websocket simultáneas , lo cual es una locura. Ahora, tuvo que hacer un poco de configuración personalizada, pero eso no lo hace menos impresionante. Esta es exactamente la razón por la que empresas como IBM, Microsoft y PayPal están utilizando Node para sus servicios web.
Ahora, Node ni siquiera necesita ser rápido para hacerlo atractivo. Una de mis funciones favoritas es en realidad el administrador de paquetes, npm . Muchos lenguajes carecen de un buen administrador de paquetes como este. npm es una herramienta de línea de comandos que puede utilizar para inicializar módulos, administrar dependencias o ejecutar pruebas, entre otras cosas.
El repositorio público está abierto para que cualquiera pueda descargar y publicar código. En el momento de escribir este artículo, npm aloja más de 210.000 módulos, que van desde sitios web hasta herramientas de línea de comandos y envoltorios de API.
Aquí hay un ejemplo de un paquete que creé. Puede ver que la página principal es README, que describe qué hace el paquete y cómo usarlo. También obtiene un resumen rápido de otra información, como el número de descargas, la ubicación del repositorio y la licencia de software utilizada.
Te puede interesar:Administrar variables de entorno en Node.js con dotenvPara que sirve Node
Entre otras cosas, Node es probablemente el más adecuado para crear sitios web y herramientas que requieren interacción sincrónica en tiempo real. Los sitios / aplicaciones de chat son un buen ejemplo de esto, ya que generalmente son muy pesados. El modelo controlado por eventos sin bloqueo le permite manejar muchas solicitudes simultáneamente.
También es muy bueno para crear el front-end para API web (a través de REST). Esto se debe a que está optimizado para E / S impulsado por eventos (que ya mencioné) y maneja JSON de forma nativa, por lo que se necesita muy poco o ningún análisis.
Para qué no es bueno Node
En el otro extremo, veamos en qué no es bueno Node. En particular, no es adecuado para realizar tareas informáticas pesadas. Entonces, si quisiera hacer algo como el aprendizaje automático con Node, probablemente no tenga la mejor experiencia.
Node también es bastante joven, por lo que todavía está en rápido desarrollo. En los últimos meses hemos pasado de v0.12.x
a v5.1.x
. Entonces, si necesita algo más estable, probablemente esto no sea para usted.
Y en cuanto al «problema» de la programación asincrónica, creo que la primera parte de esta respuesta de Quora hace un buen trabajo al explicarlo:
[Su] falta de organización de código inherente es una gran desventaja. Se agrava especialmente cuando el equipo de desarrollo en su conjunto no está familiarizado con la programación asincrónica o los patrones de diseño estándar. Hay demasiadas formas en las que el código se vuelve rebelde y no se puede mantener.
Aunque la programación asincrónica es algo bueno en general, agrega complejidad a sus programas.
El REPL de nodo
Ok, pasemos al código. Vamos a comenzar de forma bastante simple y solo ejecutaremos algunos comandos en el REPL (ciclo de lectura-evaluación-impresión), que es solo una aplicación que le permite ejecutar interactivamente el código de nodo en un shell. Un programa escrito aquí se ejecuta por partes en lugar de todos a la vez.
Asumiré que ya está familiarizado con JavaScript, por lo que repasaremos algunos aspectos específicos de Node a lo largo de este artículo.
Probemos uno de los módulos integrados que vienen con Node, como el crypto
módulo.
Suponiendo que ya tiene Node instalado, ejecute el node
comando en su shell y escriba el siguiente código en el indicador línea por línea:
var crypto = require('crypto');
crypto.createHash('md5').update('hello world').digest('hex');
Después de ingresar la última línea en el REPL (o al hacer clic en el botón ‘ejecutar’ arriba), debería ver 5eb63bbbe01eeed093cb22bb8f5acdc3 impreso en la consola.
El crypto
módulo se carga usando la require()
función, que maneja la resolución y carga de código por usted. Más información sobre cómo funciona aquí .
Una vez cargado el módulo, puedes usar sus funciones, que en este caso usamos createHash()
. Dado que los REPL ejecutan el código por partes, normalmente imprimen el valor devuelto para cada línea, como vio aquí.
Puede usar REPL como este para probar rápidamente el código sin tener que escribirlo en un nuevo archivo y ejecutarlo. Es casi como un entorno sandbox de uso general.
Tu primer programa
Los REPL son divertidos y todo, pero solo nos llevarán hasta cierto punto. Así que sigamos adelante y escribamos nuestro primer programa de nodo real. No nos preocuparemos por usar módulos de terceros todavía (pero no se preocupe, lo haremos más adelante), así que veamos primero qué código integrado está disponible para nosotros. Ya se le ha proporcionado una buena cantidad de código, que incluye (pero no se limita a):
fs
: Envoltorios simples proporcionados sobre funciones POSIX estándarhttp
: Un servidor y un cliente HTTP de nivel inferioros
: Proporciona algunos métodos básicos para informarle sobre el sistema operativo subyacentepath
: Utilidades para manejar y transformar rutas de archivosurl
: Utilidades para resolución y análisis de URLutil
: Funciones de utilidad estándar como depuración, formateo e inspección
La cantidad de código incorporado no está al nivel de Python, pero hará el trabajo. Los beneficios reales vienen cuando comienza a ingresar a los módulos de terceros.
Para nuestro primer programa, crearemos una utilidad simple que determina su ubicación usando su dirección IP (un poco espeluznante, lo sé):
var http = require('http');
var options = {
hostname: 'ipinfo.io',
port: 80,
path: '/json',
method: 'GET'
};
var req = http.request(options, function(res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
var json = JSON.parse(body);
console.log('Your location: ' + json.city + ', ' + json.region);
});
});
req.end();
Copie el código anterior y péguelo en un archivo llamado ‘index.js’. Luego, en la línea de comando, navegue hasta el directorio con el archivo que acaba de crear y ejecútelo con:
$ node index.js
Debería ver ‘Su ubicación: [CIUDAD], [REGIÓN]’ impresa en la línea de comando. La ciudad / región impresa probablemente estará bastante cerca de usted, pero no exacta. Además, si no se imprime ninguna ciudad / región, eso solo significa que su información de IP no estaba en la base de datos.
Dado que este código no usa dependencias de terceros, no necesita tener un package.json
archivo o node_modules
carpeta, sobre lo cual explicaremos más en la siguiente sección.
Tu primer paquete
Tenga en cuenta que a lo largo de este artículo utilizo ‘paquete’ y ‘módulo’ indistintamente.
Te puede interesar:Zsh contra BashPara casi todos los sitios web / herramientas / proyectos que cree con Node.js, también querrá crear un módulo a su alrededor. Esto es para que pueda especificar dependencias, pruebas, scripts, repositorios, etc.
Un módulo típico consta de algunas cosas importantes:
- package.json : un archivo JSON que contiene toda la información del módulo
- node_modules /: un directorio que contiene todas las dependencias
- index.js: el archivo de código principal
- README.md: documentación sobre el módulo
- test /: un directorio de pruebas para el módulo
Hay muchas otras cosas que puede agregar a un módulo (como un archivo .npmignore, un directorio de documentos o archivos de configuración del editor), pero las cosas enumeradas anteriormente son algunas de las más comunes que verá.
Para mostrar cómo funciona todo esto, en el resto de esta sección crearemos nuestro propio paquete que se basa en el ejemplo anterior.
En lugar de simplemente decirle su ubicación en función de su dirección IP, usaremos algunos paquetes populares de Node para crear una herramienta que le permita encontrar la ubicación del servidor de cualquier sitio web. Lo llamaremos twenty
( ver por qué ).
Inicializando el paquete
Primero, cree y navegue a un nuevo directorio para su proyecto:
$ mkdir twenty
$ cd twenty
Luego, use npm para inicializar el proyecto:
$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (twenty)
version: (0.0.1)
description: Locates the city/region of a given URL/IP address
entry point: (index.js)
test command:
git repository:
keywords:
license: (MIT)
About to write to /Users/scott/projects/twenty/package.json:
{
"name": "twenty",
"version": "0.0.1",
"description": "Locates the city/region of a given URL/IP address",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "Scott Robinson <[email protected]> (http://Pharos.sh.com)",
"license": "MIT"
}
Is this ok? (yes) yes
Complete cada mensaje (comenzando en name: (twenty)
) o no ingrese nada y simplemente presione regresar para usar la configuración predeterminada. Esto creará un package.json
archivo configurado correctamente que contiene el siguiente JSON:
{
"name": "twenty",
"version": "0.0.1",
"description": "Locates the city/region of a given URL/IP address",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": "Scott Robinson <[email protected]> (http://Pharos.sh.com)",
"license": "MIT"
}
Este archivo es su punto de partida donde se guarda toda la información específica del proyecto.
Instalar dependencias
Para agregar dependencias a su proyecto, puede usar el npm install
comando desde la línea de comandos. Por ejemplo, para agregar nuestra primera dependencia request
, intente ejecutar esto:
$ npm install --save request
El install
comando descargará el último request
paquete de npm y lo guardará en el node_modules
directorio. Agregar la --save
bandera le dice a npm que guarde los detalles del paquete en package.json en la sección ‘dependencias’:
"dependencies": {
"request": "2.67.0"
}
Ahora podrá utilizar el request
módulo en cualquier parte del código de su proyecto.
Mejorando el código
El request
módulo le brinda funciones para realizar fácilmente todo tipo de solicitudes HTTP. El ejemplo de HTTP que mostramos anteriormente no fue tan malo, pero request
hace que el código sea aún más compacto y fácil de leer. El código equivalente que se usa request
se vería así:
var request = require('request');
request('http://ipinfo.io/json', function(error, response, body) {
var json = JSON.parse(body);
console.log('Your location: ' + json.city + ', ' + json.region);
});
Sería más interesante si pudiéramos encontrar la ubicación de cualquier dirección IP, y no solo la nuestra, así que permitamos que el usuario ingrese una dirección IP como argumento de línea de comando. Como esto:
$ node index.js 8.8.8.8
Para acceder a este argumento dentro de nuestro programa, Node lo hace disponible en el process
objeto global como process.argv
, que es una matriz. Para el comando que acabamos de ejecutar arriba, process.argv
sería ['node', 'index.js', '8.8.8.8']
.
Para facilitar aún más las cosas, usaremos el paquete yargs para ayudarnos a analizar los argumentos de la línea de comandos. Con un programa simple como este, yargs
no es realmente necesario, pero mejoraré twenty
en un artículo posterior, por lo que también podríamos agregarlo ahora.
Al igual que request
, lo instalaremos con:
$ npm install --save yargs
Modificando el código a usar yargs
para tomar el argumento (o por defecto a nuestra propia IP si no se dio ningún argumento), terminamos con esto:
var request = require('request');
var argv = require('yargs').argv;
var path="json";
path = argv._[0] || path;
request('http://ipinfo.io/' + path, function(error, response, body) {
var json = JSON.parse(body);
console.log('Server location: ' + json.city + ', ' + json.region);
});
Hasta ahora, esta herramienta es excelente para el uso de la línea de comandos, pero ¿qué pasa si alguien quiere usarla como una dependencia en su propio código? A partir de ahora, el código no se ha exportado, por lo que no podrá usarlo en ningún otro lugar que no sea la línea de comandos. Para decirle a Node qué funciones / variables hacer disponibles, podemos usar module.exports
.
var request = require('request');
var argv = require('yargs').argv;
var findLocation = function(ip, callback) {
var path;
if (typeof(ip) === 'function' || !ip) path="json";
else path = ip;
request('http://ipinfo.io/' + path, function(error, response, body) {
var json = JSON.parse(body);
callback(null, json.city + ', ' + json.region);
});
};
module.exports = findLocation;
¡Genial! Ahora cualquiera que descargue este paquete puede solicitarlo en cualquier parte de su código y usar la findLocation()
función.
Pero, es posible que haya notado que ahora ya no podemos usarlo como una herramienta de línea de comandos. Sin embargo, no queremos poner el resto del código antiguo así:
var request = require('request');
var argv = require('yargs').argv;
var findLocation = function(ip, callback) {
var path;
if (typeof(ip) === 'function' || !ip) path="json";
else path = ip;
request('http://ipinfo.io/' + path, function(error, response, body) {
var json = JSON.parse(body);
callback(null, json.city + ', ' + json.region);
});
};
var arg = argv._[0] || path;
// This runs every time the file is loaded
findLocation(arg, function(err, location) {
console.log('Server location: ' + location);
});
module.exports = findLocation;
Esto sería malo porque cada vez que alguien require()
use este archivo para usar la findLocation()
función, imprimirá su propia ubicación en la línea de comandos. Necesitamos una forma de determinar si este archivo fue llamado directamente con node index.js
y no por require()
, así que si fue llamado directamente, revisaremos la línea de comando para ver los argumentos. Esto se puede hacer mediante la comprobación require.main
en contra module
, como este: if (require.main === module) {...}
, lo que nos deja con:
var request = require('request');
var argv = require('yargs').argv;
var findLocation = function(ip, callback) {
var path;
if (typeof(ip) === 'function' || !ip) path="json";
else path = ip;
request('http://ipinfo.io/' + path, function(error, response, body) {
var json = JSON.parse(body);
callback(null, json.city + ', ' + json.region);
});
};
if (require.main === module) {
findLocation(argv._[0], function(err, location) {
console.log('Server location: ' + location);
});
}
module.exports = findLocation;
Ahora podemos usar este código tanto en la línea de comando como como dependencia.
Nota: Hay una mejor manera de hacer el híbrido CLI / biblioteca, pero lo mantendremos simple y nos quedaremos con este método por ahora. Consulte veinte en Github para obtener más información, específicamente el bin
directorio y la package.json
configuración.
Publicando su paquete
Finalmente, queremos que esté disponible para otros en npm. Todo lo que necesita hacer para que el paquete esté disponible es ejecutar esto en el directorio del paquete:
$ npm publish
Se le pedirá su nombre de usuario y contraseña, y luego el código se enviará al registro.
Tenga en cuenta que deberá ajustar el alcance de su paquete o cambiar su nombre, ya que el nombre ‘veinte’ ya lo he utilizado.
A dónde ir desde aquí
Con la popularidad de Node en auge, hay toneladas de recursos en Internet. Estos son algunos de los libros y cursos más populares con los que me he encontrado, que le enseñarán mucho más de lo que pude mostrar aquí:
- Aprenda Node.js de Wes Bos
- Desarrollo web Node.js: desarrollo del lado del servidor con Node 10
- Patrones de diseño de Node.js: domine las mejores prácticas para crear aplicaciones web modulares y escalables del lado del servidor
- Comenzando con Node.js
O si desea seguir con algunos tutoriales más cortos, aquí hay algunos de Stack Abuse que pueden ser útiles:
- Evitar el infierno de devolución de llamada en Node.js
- Paquetes de nodos útiles que quizás no conozca
- Clases de ES6
- Ejecutar tareas periódicas en Node con node-cron
Solo tenga en cuenta que la gran mayoría de lo que aprenderá será de su propia exploración del lenguaje, las herramientas y los paquetes. Entonces, aunque artículos como este son buenos para comenzar, asegúrese de enfocarse más en escribir código que en leer sobre alguien más escribiendo código. La experiencia triunfa sobre todo lo demás.
Conclusión
Solo cubrimos una pequeña fracción de lo que Node y npm tienen para ofrecer, así que consulte algunos de los recursos a los que he vinculado anteriormente para obtener más información.
Y no puedo enfatizar lo suficiente lo importante que es para ti adquirir experiencia escribiendo código. npm hace que sea realmente fácil buscar paquetes y encontrar sus repositorios. Así que busque un paquete que sea útil o interesante para usted y vea cómo funciona.
¿Eres un novato de Node? ¿Qué otros temas de Node quieres aprender? ¡Háznoslo saber en los comentarios!
Te puede interesar:Validación de forma angular