Fundamentos de Node.js:una descripción general concisa de los conceptos principales

Node.js es una plataforma de E/S sin bloqueo altamente eficiente y escalable que se creó sobre el motor Google Chrome V8 y su ECMAScript. Esto significa que la mayoría de los objetos, funciones y métodos de JavaScript front-end (otra implementación de ECMAScript) están disponibles en Node.js. Consulte Conceptos básicos de JavaScript si necesita refrescar los conceptos básicos específicos de JS.

Los desarrolladores pueden instalar Node.js desde su sitio web y seguir esta descripción general de los conceptos principales de Node.js. Para obtener instrucciones más detalladas de Node.js, eche un vistazo a Rapid Prototyping with JS:Agile JavaScript Development and Node School.

Read-Eval-Print Loop (también conocido como Consola) en Node.js

Al igual que en muchos otros lenguajes y plataformas de programación, Node.js tiene una herramienta de bucle de lectura, evaluación e impresión que abre $ node dominio. El indicador cambia a > y podemos ejecutar JavaScript similar a la consola de Chrome Developer Tools. Existen ligeras desviaciones en las implementaciones de ECMAScript en Node.js y navegadores (p. ej., {}+{} ), pero en su mayor parte los resultados son similares.

Entonces, como puede ver, podemos escribir JavaScript en la consola durante todo el día, pero en algún momento podemos guardar el script para poder ejecutarlo más tarde.

Ejecución de secuencias de comandos de Node.js

Para iniciar un script de Node.js desde un archivo, simplemente ejecute $ node filename , por ejemplo, $ node program.js . Si todo lo que necesitamos es un conjunto rápido de declaraciones, hay un -e opción que permite ejecutar JavaScript/Node.js en línea, por ejemplo, $ node -e "console.log(new Date());" .

Información del proceso de Node.js

Cada script de Node.js que se ejecuta es un proceso en esencia. Por ejemplo, ps aux | grep 'node' generará todos los programas Node.js que se ejecutan en una máquina. Convenientemente, los desarrolladores pueden acceder a información útil del proceso en código con process objeto, por ejemplo, node -e "console.log(process.pid)" :

Acceso al alcance global en Node.js

Como sabe por JS FUNdamentals, el JavaScript del navegador por defecto pone todo en su alcance global. Esto fue acuñado como una de las partes malas de JavaScript en el famoso [JavaScript:The Good Parts] de Douglas Crockford. Node.js fue diseñado para comportarse de manera diferente con todo siendo local por defecto. En caso de que necesitemos acceder a globales, hay un global objeto. Asimismo, cuando necesitemos exportar algo, debemos hacerlo de forma explícita.

En cierto sentido, window objeto de front-end/navegador JavaScript transformado en una combinación de global y process objetos. No hace falta decir que el document el objeto que representa el DOM de la página web no existe en Node.js.

Exportación e importación de módulos

Otra mala parte en el navegador JavaScript es que no hay forma de incluir módulos. Se supone que los scripts se vinculan entre sí usando un lenguaje diferente (HTML) con una gestión de dependencia que carece. CommonJS y RequireJS resuelven este problema con el enfoque AJAX-y. Node.js tomó prestadas muchas cosas del concepto CommonJS.

[Nota al margen]

Leer publicaciones de blog es bueno, pero ver cursos en video es aún mejor porque son más atractivos.

Muchos desarrolladores se quejaron de la falta de material de video de calidad asequible en Node. Es una distracción ver videos de YouTube y una locura pagar $ 500 por un curso de video de Node.

Visite Node University, que tiene cursos de video GRATUITOS en Node:node.university.

[Fin de la nota al margen]

Para exportar un objeto en Node.js, use exports.name = object; , por ejemplo,

var messages = {
  find: function(req, res, next) {
  ...
  },
  add: function(req, res, next) {
  ...
  }, 
  format: 'title | date | author'
}
exports.messages = messages;

Mientras que en el archivo donde importamos el script mencionado anteriormente (asumiendo que la ruta y el nombre del archivo son route/messages.js ):

var messages = require('./routes/messages.js');

Sin embargo, en algún momento es más apropiado invocar un constructor, por ejemplo, cuando adjuntamos propiedades a la aplicación Express.js (más sobre Express.js en Express.js FUNdamentals:An Essential Overview of Express.js). En este caso module.exports se necesita:

module.exports = function(app) {
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  return app;
}

En el archivo que incluye el módulo de ejemplo anterior:

...
var app = express();
var config = require('./config/index.js');
app = config(app);
...

El código más sucinto:var = express(); require('./config/index.js')(app); .

El error más común al incluir módulos es una ruta incorrecta al archivo. Para los módulos principales de Node.js, solo use el nombre sin ninguna ruta, por ejemplo, require('name'). Lo mismo ocurre con los módulos en node_modules carpeta. Más sobre eso más adelante en la sección NPM.

Para todos los demás archivos, use . con o sin una extensión de archivo, por ejemplo,

var keys = require('./keys.js'),
  messages = require('./routes/messages.js');

Además, para la última categoría es posible usar declaraciones más largas con __dirname y path.join() , por ejemplo, require(path.join(__dirname, ,'routes', 'messages'));`

Si require() apunta a una carpeta, Node.js intentará leer index.js archivo en esa carpeta.

Buffer es un supertipo de datos de Node.js

Buffer es una adición de Node.js a cuatro elementos primitivos (booleano, cadena, número y RegExp) y objetos que lo abarcan todo (la matriz y las funciones también son objetos) en el front-end de JavaScript. Podemos pensar en los búferes como almacenes de datos extremadamente eficientes. De hecho, Node.js intentará usar búferes cada vez que pueda, por ejemplo, leyendo desde el sistema de archivos, recibiendo paquetes a través de la red.

__dirname frente a proceso.cwd

__dirname es una ruta absoluta al archivo en el que se llamó a esta variable global, mientras que process.cwd es una ruta absoluta al proceso que ejecuta este script. Este último podría no ser el mismo que el primero si iniciamos el programa desde una carpeta diferente, por ejemplo, $ node ./code/program.js .

Utilidades útiles en Node.js

Aunque el núcleo de la plataforma Node.js se mantuvo pequeño intencionalmente, tiene algunas utilidades esenciales como

  • URL
  • Cripto
  • Ruta
  • Decodificador de cadenas

El método que usamos en estos tutoriales es path.join y concatena la ruta usando un separador de carpeta apropiado (/ o \\ ).

Lectura y escritura desde/hacia el sistema de archivos en Node.js

La lectura de archivos se realiza a través del núcleo fs módulo. Hay dos conjuntos de métodos:async y sync. En la mayoría de los casos, los desarrolladores deben usar métodos asíncronos, por ejemplo, fs.readFile:

var fs = require('fs');
var path = require('path');
fs.readFile(path.join(__dirname, '/data/customers.csv'), {encoding: 'utf-8'}, function (err, data) {
  if (err) throw err;
  console.log(data);
});

Y la escritura en el archivo:

var fs = require('fs');
fs.writeFile('message.txt', 'Hello World!', function (err) {
  if (err) throw err;
  console.log('Writing is done.');
});

Transmisión de datos en Node.js

La transmisión de datos es un término que significa que una aplicación procesa los datos mientras aún los recibe. Esto es útil para conjuntos de datos extra grandes, como migraciones de videos o bases de datos.

Aquí hay un ejemplo básico sobre el uso de flujos que devuelven el contenido del archivo binario:

var fs = require('fs');
fs.createReadStream('./data/customers.csv').pipe(process.stdout);

De forma predeterminada, Node.js usa búferes para flujos.

Para un entrenamiento más inmersivo, aprovecha Stream-Adventure y Stream Handbook.

Instalación de módulos de Node.js con NPM

NPM viene con la plataforma Node.js y permite una gestión de paquetes Node.js sin problemas. El camino npm install work es similar a Git en la forma en que atraviesa el árbol de trabajo para encontrar un proyecto actual. Para empezar, tenga en cuenta que necesitamos el package.json archivo o el node_modules carpeta, para instalar módulos localmente con $ npm install name , por ejemplo $ npm install superagent; en el programa.js:var suparagent = requier('superagent'); .

Lo mejor de NPM es que mantiene todas las dependencias locales, por lo que si el módulo A usa el módulo B v1.3 y el módulo C usa el módulo B v2.0 (con cambios importantes en comparación con v1.3), tanto A como C tendrán sus propias copias localizadas de diferentes versiones de B. Esto demuestra ser una estrategia superior a diferencia de Ruby y otras plataformas que usan instalaciones globales por defecto.

La mejor práctica es no incluir un node_modules carpeta en el repositorio de Git cuando el proyecto es un módulo que se supone que debe usarse en otra aplicación. Sin embargo, se recomienda incluir node_modules para aplicaciones desplegables. Esto evita una rotura causada por una actualización de dependencia desafortunada.

Nota:al creador de NPM le gusta llamarlo npm (minúsculas).

Hello World Server con módulo HTTP Node.js

Aunque Node.js se puede usar para una amplia variedad de tareas, se conoce principalmente para crear aplicaciones web. Node.js prospera en la red debido a su naturaleza asíncrona y módulos integrados como net y http.

Aquí hay ejemplos de Hello World por excelencia donde creamos un objeto de servidor, definimos el controlador de solicitudes (función con argumentos req y res), devolvemos algunos datos al destinatario e iniciamos todo.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');]

Los parámetros req y res tienen toda la información sobre una solicitud HTTP determinada y la respuesta correspondiente. Además, req y res se pueden usar como secuencias (consulte la sección anterior).

Depuración de programas de Node.js

El mejor depurador es console.log() , pero en algún momento necesitamos ver la pila de llamadas y orientarnos un poco más en el código asíncrono. Para ello, pon debugger declaraciones en su código y use $ node debug program.js para iniciar el proceso de depuración. Para obtener una interfaz más amigable para los desarrolladores, descargue el inspector de nodos.

Domar las devoluciones de llamada en Node.js

Las devoluciones de llamada pueden codificar Node.js de forma asíncrona, pero los programadores que no están familiarizados con JavaScript, que provienen de Java o PHP, pueden sorprenderse cuando ven el código de Node.js descrito en Callback Hell:

fs.readdir(source, function(err, files) {
  if (err) {
    console.log('Error finding files: ' + err)
  } else {
    files.forEach(function(filename, fileIndex) {
      console.log(filename)
      gm(source + filename).size(function(err, values) {
        if (err) {
          console.log('Error identifying file size: ' + err)
        } else {
          console.log(filename + ' : ' + values)
          aspect = (values.width / values.height)
          widths.forEach(function(width, widthIndex) {
            height = Math.round(width / aspect)
            console.log('resizing ' + filename + 'to ' + height + 'x' + height)
            this.resize(width, height).write(destination + 'w' + width + '_' + filename, function(err) {
              if (err) console.log('Error writing file: ' + err)
            })
          }.bind(this))
        }
      })
    })
  }
})

No hay nada que temer aquí siempre que se use una sangría de dos espacios.;-) Sin embargo, el código de devolución de llamada se puede reescribir con el uso de emisores de eventos, promesas o utilizando la biblioteca asíncrona.

Introducción a Node.js con Ryan Dahl

Por último, pero no menos importante:

Avanzando con Express.js

Una vez que haya dominado los conceptos básicos de Node.js en este artículo, es posible que desee leer Express.js FUNdamentals:An Essential Overview of Express.js y considere trabajar en una clase interactiva sobre el marco Express.js que, a partir de hoy, es el módulo más popular en NPM.