Creación de su primera aplicación de línea de comandos de Node.js

Las utilidades de línea de comandos son imprescindibles para todos los desarrolladores web experimentados. Node.js hace que el desarrollo de tales herramientas sea extremadamente fácil gracias a una gran cantidad de módulos de código abierto y un excelente administrador de paquetes.

En este tutorial, convertiremos nuestro Cute File Browser, que publicamos la semana pasada, de PHP a Node. Nuestro objetivo es crear una utilidad de línea de comandos que los usuarios puedan iniciar en su máquina y hacer que cualquier carpeta esté disponible en la red local. Esto se puede usar en una configuración de hogar u oficina para compartir rápidamente una carpeta con archivos para todos en la misma red.

Inicio rápido

El código fuente está disponible en github y npm. Si no quieres seguir este tutorial y solo quieres jugar con él, puedes instalarlo directamente con este comando:

npm install -g cute-files

Luego, navega a la carpeta que deseas compartir en tu terminal y ejecuta el comando que acabas de instalar:

cute-files

Ahora esa carpeta estará disponible en <yourip>:3000 y será accesible para cualquier persona en su LAN.

Vamos a construirlo paso a paso

Las utilidades de línea de comandos son solo programas de nodo normales. Están disponibles globalmente y se pueden llamar desde cualquier carpeta. Por lo tanto, los pasos para crear nuestra aplicación de línea de comandos son casi idénticos a los de cualquier otro proyecto basado en nodos que haya desarrollado antes. Cree una nueva carpeta para su proyecto y navegue hasta ella en su terminal. Nos referiremos a ella como su carpeta de proyecto .

Configurando paquete.json

Suponiendo que ya ha instalado el nodo, primero debemos crear un package.json expediente. La utilidad npm puede ayudarlo con eso. Ejecute este comando en la carpeta de su proyecto:

npm init

Se le pedirá información sobre su proyecto. Si no está seguro de qué escribir, simplemente presione regresar para obtener los valores predeterminados. Complete cute-files.js como punto de entrada. Este será el archivo principal, que será llamado por node. El paquete.json aún no está completo; queremos que nuestro script esté disponible globalmente, por lo que debemos agregar un campo adicional:bin (ver mi paquete.json como ejemplo). Esto le dice a npm que haga que estos scripts estén disponibles como ejecutables.

Instalando algunos paquetes

Ahora deberá instalar algunas bibliotecas que necesitamos para el explorador de archivos. El --guardar flag los agregará a su paquete.json automáticamente:

npm install commander content-disposition express --save

Esto es para lo que los usaremos:

  • el comando analizará los argumentos de la línea de comandos. Solo admitiremos uno:para el puerto , pero dado que el análisis de atributos es una parte fundamental de la escritura de aplicaciones de línea de comandos, es bueno saber cómo usar esta biblioteca.
  • content-disposition nos dirá los encabezados adjuntos correctos para cada archivo. Estos encabezados son necesarios para forzar la descarga de los archivos (de lo contrario, el navegador simplemente los abriría).
  • express entregará los archivos y se encargará de /escanear ruta que envía un JSON de todos los archivos y directorios a la interfaz.

Módulo para escanear archivos

Para ofrecer búsqueda y navegación instantáneas, nuestra aplicación enviará un JSON con todos los archivos y carpetas a la interfaz cargada. En el tutorial original, hicimos esto con PHP, pero ahora lo haremos con Node. Cree un nuevo archivo en la carpeta del proyecto:scan.js - y pega el siguiente código:

var fs = require('fs'),
    path = require('path');

module.exports = function scan(dir, alias){

    return {
        name: alias,
        type: 'folder',
        path: alias,
        items: walk(dir, alias)
    };

};

function walk(dir, prefix){

    prefix = prefix || '';

    if(!fs.existsSync(dir)){
        return [];
    }

    return fs.readdirSync(dir).filter(function(f){

        return f && f[0] != '.'; // Ignore hidden files

    }).map(function(f){

        var p = path.join(dir, f),
            stat = fs.statSync(p);

        if(stat.isDirectory()){

            return {
                name: f,
                type: 'folder',
                path: path.join(prefix, p),
                items: walk(p, prefix)
            };

        }

        return {
            name: f,
            type: 'file',
            path: path.join(prefix, p),
            size: stat.size
        }

    });

};

Este código usa el módulo fs de node y recorre recursivamente todos los archivos y carpetas en un directorio. Exporta el escaneo función a la que se llama con una ruta y un alias. La ruta es la carpeta a escanear y el alias es el nombre con el que se presentará en la interfaz (no queremos mostrar el nombre real del directorio que se sirve). En nuestro ejemplo, lo reemplazamos con "archivos".

Módulo principal

El archivo principal de nuestra aplicación es cute-files.js . Cree el archivo y pegue el siguiente código:

#!/usr/bin/env node

var path = require('path');
var express = require('express');
var contentDisposition = require('content-disposition');
var pkg = require( path.join(__dirname, 'package.json') );

var scan = require('./scan');

// Parse command line options

var program = require('commander');

program
    .version(pkg.version)
    .option('-p, --port <port>', 'Port on which to listen to (defaults to 3000)', parseInt)
    .parse(process.argv);

var port = program.port || 3000;

// Scan the directory in which the script was called. It will
// add the 'files/' prefix to all files and folders, so that
// download links point to our /files route

var tree = scan('.', 'files');

// Ceate a new express app

var app = express();

// Serve static files from the frontend folder

app.use('/', express.static(path.join(__dirname, 'frontend')));

// Serve files from the current directory under the /files route

app.use('/files', express.static(process.cwd(), {
    index: false,
    setHeaders: function(res, path){

        // Set header to force files to download

        res.setHeader('Content-Disposition', contentDisposition(path))

    }
}));

// This endpoint is requested by our frontend JS

app.get('/scan', function(req,res){
    res.send(tree);
});

// Everything is setup. Listen on the port.

app.listen(port);

console.log('Cute files is running on port ' + port);

La primera línea es importante. Aunque no es JS válido, se usa en sistemas *nix para permitir que los scripts se ejecuten como programas, que es exactamente lo que necesitamos para hacer los cute-files comando disponible en cualquier lugar.

Este script usa express y los otros módulos que instalamos previamente, y nuestro módulo scan.js. Todo lo que queda es copiar la parte frontal del tutorial original.

La interfaz

Nick ya hizo la mayor parte del trabajo en el tutorial de la semana pasada. Nuestro script scan.js devuelve el mismo resultado que scan.php, por lo que no es necesario modificar la interfaz. Solo necesitamos copiar sobre index.html y los activos carpeta de la última vez a una nueva carpeta - frontend , que será servido por express. Puede ver cómo deberían verse sus directorios desde el repositorio.

Vincular el módulo

¡Tu nuevo módulo está listo! Debería funcionar cuando ejecutas node cute-files.js en la carpeta del proyecto. Pero esto no es muy útil, ya que solo servirá la carpeta del proyecto; queremos poder llamar a los cute-files comando desde cualquier directorio, pero no está disponible a menos que instale el módulo globalmente. npm tiene un comando útil que nos ayudará. Ejecute esto en su terminal desde la carpeta del proyecto:

npm link

Esto hará que el módulo esté disponible a nivel mundial, por lo que ahora puede usar los cute-files ¡comando en cualquier lugar!

Publicación en npm

¿Dónde está la diversión de escribir un módulo y no compartirlo con tus amigos? Es sencillo publicar su nuevo módulo en npm (sin embargo, le aconsejo que no lo haga para este módulo específico; solo será un duplicado de lindos archivos):

  1. Cree una cuenta en el sitio web de npm
  2. Inicie sesión desde la utilidad de línea de comandos npm con npm login comando
  3. Elija un nombre único para su módulo y actualice package.json
  4. cd en la carpeta del proyecto y ejecuta npm publish .

Si todo salió bien, en unos segundos verá su módulo en el sitio web de npm y todos podrán instalarlo.

¡Buen trabajo! ¡Acabas de crear tu primera aplicación de línea de comandos con node!