Aprender Node.js: Gu铆a para principiantes

    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

    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.

    Para 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.xa 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 cryptom贸dulo.

    Suponiendo que ya tiene Node instalado, ejecute el nodecomando 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 cryptom贸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谩ndar
    • http: Un servidor y un cliente HTTP de nivel inferior
    • os: Proporciona algunos m茅todos b谩sicos para informarle sobre el sistema operativo subyacente
    • path: Utilidades para manejar y transformar rutas de archivos
    • url: Utilidades para resoluci贸n y an谩lisis de URL
    • util: 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.jsonarchivo o node_modulescarpeta, 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.

    Para 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.jsonarchivo 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 installcomando desde la l铆nea de comandos. Por ejemplo, para agregar nuestra primera dependencia request, intente ejecutar esto:

    $ npm install --save request
    

    El installcomando descargar谩 el 煤ltimo requestpaquete de npm y lo guardar谩 en el node_modulesdirectorio. Agregar la --savebandera 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 requestm贸dulo en cualquier parte del c贸digo de su proyecto.

    Mejorando el c贸digo

    El requestm贸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 requesthace que el c贸digo sea a煤n m谩s compacto y f谩cil de leer. El c贸digo equivalente que se usa requestse 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 processobjeto global como process.argv, que es una matriz. Para el comando que acabamos de ejecutar arriba, process.argvser铆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, yargsno es realmente necesario, pero mejorar茅 twentyen 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 yargspara 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.jsy 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.mainen 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 bindirectorio y la package.jsonconfiguraci贸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铆:

    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!

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *