Cómo crear un JavaScript que permite copiar una o varias carpetas de ficheros origen en uno o varios destinos de forma asíncrona, ejecutando varias copias concurrentemente. Explicamos también cómo usar Node.js para interpretar el JavaScript y cómo usar JXcore para generar un ejecutable .exe a partir del fichero JavaScript, permitiendo de esta forma ejecutar el JavaScript en cualquier PC sin necesidad de instalar software de terceros.

Funcionamiento y utilidad del código JavaScript

El código JavaScript que mostraremos a continuación usa un fichero con formato JSON donde se introducen las carpetas origen a copiar y los distintos destinos de copia. Un ejemplo del contenido de este fichero JSON que llamaremos «actualizar.json»:

Funcionamiento y utilidad del código JavaScript

Básicamente se introduce un nombre para el grupo de copia, por ejemplo «FACTURACION» y a continuación se establece un origen y los destinos de copia. En el ejemplo anterior se copiarán los ficheros de la carpeta:

\\servidor\\software\\Facturacion

a los equipos:

\\PC44\c$\Users\Domingo\Facturacion
\
\PC40\c$\Users\Juan\Facturacion
\\SRVFACTURACION\Facturacion

Y también se copiará el contenido de la carpeta:

\\servidor\software\Contabilidad

a los equipos:

\\PC66\c$\Users\Fernando\Contabilidad
\\SRVCONTA\Contabilidad

Como vemos este ejemplo que mostraremos a continuación puede ser útil para actualizar aplicaciones de escritorio cliente/servidor pues permite especificar varios orígenes (varias carpetas) y varios destinos a los que copiar los orígenes. Además de que gracias al método asíncrono, el script copiará varios ficheros a la vez (hasta el límite establecido por concurrency).

Este script en JavaScript también realizará un ping inicial a cada destino de copia para comprobar si está disponible. Dicho ping también lo lanzará en modo asíncrono, lanzando varios ping a la vez, hasta el límite establecido por concurrency.

Código JavaScript para copiar carpetas a varios destinos de forma asíncrona

A continuación mostramos el código del script completo en JavaScript que permitirá leer el fichero JSON de configuración para copiar los ficheros de las carpetas origen a los destinos especificados. Además de realizar un ping a todos los equipos destino para verificar su disponibilidad:

Código JavaScript para copiar carpetas a varios destinos de forma asíncrona

El siguiente código puede descargarse gratuitamente pulsando aquí:

Será suficiente con copiar el código anterior en un fichero de texto plano sin formato y llamarlo, por ejemplo, actualizar.js.

Cómo interpretar y ejecutar JavaScript mediante Node.js

Una vez creado el fichero JavaScript como hemos indicando anteriormente, ahora tendremos que ejecutarlo para que realice su función. A continuación explicamos los pasos a seguir para interpretar o ejecutar un fichero JavaScript desde fuera de un navegador, desde nuestro equipo de escritorio, como si se tratara de una aplicación o comando Windows. Para ello usaremos la herramienta Node.js que es de libre distribución y sirve, entre otras cosas, para interpretar código JavaScript desde fuera del navegador.

Qué es Node.js

Antes de continuar con nuestro script vamos a aportar un poco de teoría sobre Node.js, que nos ayudará a entender para qué sirve y cuáles son sus características. Node.js es un entorno en tiempo de ejecución multiplataforma, de código abierto, para la capa del servidor (pero no limitándose a ello) basado en el lenguaje de programación ECMAScript, asíncrono, con I/O de datos en una arquitectura orientada a eventos y basado en el motor V8 de Google. Fue creado con el enfoque de ser útil en la creación de programas de red altamente escalables, como por ejemplo, servidores web.

Node.js es similar en su propósito a Twisted o Tornado de Python, Perl Object Environment de Perl, React de PHP, libevent o libev de C, EventMachine de Ruby, vibe.d de D y de Java existe Apache MINA, Netty, Akka, Vert.x, Grizzly o Xsocket. Al contrario que la mayoría del código JavaScript, no se ejecuta en un navegador, sino en el servidor. Node.js implementa algunas especificaciones de CommonJS. Node.js incluye un entorno REPL para depuración interactiva.

Algunos aspectos técnicos interesantes de Node.js:

  • Paralelismo: Node.js funciona con un modelo de evaluación de un único hilo de ejecución, usando entradas y salidas asíncronas las cuales pueden ejecutarse concurrentemente en un número de hasta cientos de miles sin incurrir en costos asociados al cambio de contexto. Este diseño de compartir un único hilo de ejecución entre todas las solicitudes atiende a necesidades de aplicaciones altamente concurrentes, en el que toda operación que realice entradas y salidas debe tener una función callback. Un inconveniente de este enfoque de único hilo de ejecución es que Node.js requiere de módulos adicionales como cluster para escalar la aplicación con el número de núcleos de procesamiento de la máquina en la que se ejecuta.
  • V8: es el ambiente de ejecución para JavaScript creado para Google Chrome. Es software libre desde 2008, está escrito en C++ y compila el código fuente JavaScript en código de máquina en lugar de interpretarlo en tiempo real. Node.js contiene libuv para manejar eventos asíncronos. Libuv es una capa de abstracción de funcionalidades de redes y sistemas de archivo en sistemas Windows y sistemas basados en POSIX como Linux, Mac OS X y Unix. El cuerpo de operaciones de base de Node.js está escrito en JavaScript con métodos de soporte escritos en C++.
  • Módulos: Node.js incorpora varios «módulos básicos» compilados en el propio binario, como por ejemplo el módulo de red, que proporciona una capa para programación de red asíncrona y otros módulos fundamentales, como por ejemplo Path, FileSystem, Buffer, Timers y el de propósito más general Stream. Es posible utilizar módulos desarrollados por terceros, ya sea como archivos «.node» precompilados, o como archivos en JavaScript plano. Los módulos JavaScript se implementan siguiendo la especificación CommonJS para módulos, utilizando una variable de exportación para dar a estos scripts acceso a funciones y variables implementadas por los módulos. Los módulos de terceros pueden extender Node.js o añadir un nivel de abstracción, implementando varias utilidades middleware para utilizar en aplicaciones web, como por ejemplo los frameworks connect y express. Pese a que los módulos pueden instalarse como archivos simples, normalmente se instalan utilizando el Node Package Manager (npm) que nos facilitará la compilación, instalación y actualización de módulos así como la gestión de las dependencias. Además, los módulos que no se instalen en el directorio por defecto de módulos de Node necesitarán la utilización de una ruta relativa para poder encontrarlos.
  • Desarrollo homogéneo entre cliente y servidor. Node.js puede ser combinado con una base de datos documental (por ejemplo, MongoDB o CouchDB) y JSON lo que permite desarrollar en un ambiente de desarrollo JavaScript unificado. Con la adaptación de los patrones para desarrollo del lado del servidor tales como MVC y sus variantes MVP, MVVM, etc. Node.js facilita la reutilización de código del mismo modelo de interfaz entre el lado del cliente y el lado del servidor.
  • Lazo de eventos. Node.js se registra con el sistema operativo y cada vez que un cliente establece una conexión se ejecuta un callback. Dentro del ambiente de ejecución de Node.js, cada conexión recibe una pequeña asignación de espacio de memoria dinámico, sin tener que generar un hilo de trabajo. A diferencia de otros servidores dirigidos por eventos, el lazo de manejo de eventos de Node.js no es llamado explícitamente sino que se activa al final de cada ejecución de una función de callback. El lazo de manejo de eventos se termina cuando ya no quedan eventos por atender.

Instalar Node.js en un equipo Windows

En primer lugar descargaremos el instalador apropiado para nuestro sistema operativo de la web oficial de Node.js, para ello accederemos a la URL:

Y descargaremos la versión estable, en nuestro caso «v5.0.0 Stable»:

Instalar Node.js en un equipo Windows

Guardaremos el fichero node-v5.0.0-x64.msi:

Instalar Node.js en un equipo Windows

Ejecutaremos el fichero descaragado:

Instalar Node.js en un equipo Windows

Es posible que nos muestre un mensaje de advertencia de seguridad, pulsaremos «Ejecutar»:

Instalar Node.js en un equipo Windows

Se iniciará el asistente de instalación de Node.js, pulsaremos «Next»:

Instalar Node.js en un equipo Windows

Leeremos los términos de licencia, si estamos de acuerdo marcaremos «I accept the terms in the Licence Agreement» y pulsaremos «Next»:

Instalar Node.js en un equipo Windows

Pulsaremos «Next»:

Instalar Node.js en un equipo Windows

Se instalarán las siguientes herramientas:

  • Node.js runtime.
  • npm package manager.
  • Online documentation shorcuts.
  • Se añadirá a la variable PATH del sistema la ruta de instalación para ejecutar estas herramientas desde cualquier carpeta.

Pulsaremos «Install» para iniciar la instalación de Node.js:

Instalar Node.js en un equipo Windows

El asistente nos indicará que Node.js ha sido instalado correctamente en nuestro equipo:

Instalar Node.js en un equipo Windows

Crear fichero JSON package.json de configuración del paquete con Node.js

Una vez instalado Node.js en nuestro equipo podremos usar sus comandos para interpretar y ejecutar código JavaScript. Antes de ejecutar nuestro script de ejemplo JavaScript actualizar.js deberemos obtener todas las librerías que hayamos necesitado (incluidas en la cláusula require) y crear el fichero package.json, necesario para la ejecución de un fichero JavaScript con Node.js. Para crear el fichero package.json usaremos Node.js, abriremos una ventana de MS-DOS (línea de comandos de Windows), para ello pulsaremos en el botón Inicio y escribiremos «cmd», nos mostrará la herramienta de shell, pulsaremos con el botón derecho del ratón sobre ella y seleccionaremos «Ejecutar como administrador»:

Crear fichero JSON package.json de configuración del paquete con Node.js

Ahora nos posicionaremos en la carpeta donde tengamos el fichero actualizar.js, en nuestro caso ejecutaremos los siguientes comandos MS-DOS:

cd..

cd..

cd AjpdSoft_JavaScript

Una vez posicionados en la carpeta con el fichero actualizar.js ejecutaremos el siguiente comando usando el paquete «npm»:

npm init

Crear fichero JSON package.json de configuración del paquete con Node.js

Nos pedirá una serie de datos (podemos dejar todos los de defecto pulsando INTRO), nos pedirá el nombre de la aplicación (name), la versión (version), la descripción (description), punto de entrada (entry point) que pode defecto suele ser el nombre del fichero .js, palabras clave, autor, licencia, etc. Introduciremos cada dato y pulsaremos INTRO. Al finalizar la captura de datos nos preguntará si es correcto (Is this ok?), pulsaremos INTRO:

Crear fichero JSON package.json de configuración del paquete con Node.js

Pulsa aquí para ver la salida comando npm init.

El comando anterior nos habrá creado el fichero package.json:

Crear fichero JSON package.json de configuración del paquete con Node.js

Pulsa aquí para ver un ejemplo de contenido de fichero package.json creado por la herramienta npm.

Descarga de las dependencias, librerías adicionales con Node.js

Si nuestro script JavaScript incluye dependencias (require) deberemos especificarlas en el fichero package.json y descargar los ficheros de cada dependencia. Para hace esto de forma automática podemos usar Node.js. En primer lugar consultaremos las dependencias que hemos usado en nuestro .js, en nuestro caso:

var colors = require(‘colors‘);
var pad = require(‘pad‘);
var path = require(‘path‘);
var Promise = require(«bluebird«);
var fs = Promise.promisifyAll(require(«fs«));
var ping = require(‘ping-bluebird‘);
var Dict = require(«collections/dict»);
var mkdirp = require(«mkdirp-then«);
var config = require(‘./actualizar.json’);

y ejecutaremos el siguiente comando (siempre en la carpeta donde se encuenta el fichero JavaScript):

npm install colors pad path bluebird fs ping-bluebird collections mkdirp-then –save

Descarga de las dependencias, librerías adicionales con Node.js

Si todo es correcto Node.js con el paquete npm descargará en una subcarpeta de nuestro proyecto todos los ficheros necesarios de cada librería o paquete usado por nuestro fichero JavaScript, mostrando el siguiente resultado:

Descarga de las dependencias, librerías adicionales con Node.js

Pulsar aquí para ver la salida del comando npm install colors pad path bluebird fs ping-bluebird collections mkdirp-then –save.

Además, el comando anterior habrá editado el fichero package.json y habrá añadido las dependencias correspondientes. También habrá creado la subcarpeta «node_modules» con los ficheros de cada librería referenciada.

Podemos consultar el contenido del fichero package.json que puede abrirse con cualquier editor de texto plano sin formato:

Descarga de las dependencias, librerías adicionales con Node.js

Vemos que ha añadido «dependencies» y todas las librerías de los requiere del fichero JavaScript que hayamos indicado que se descarguen con el comando anterior:

Descarga de las dependencias, librerías adicionales con Node.js

El contenido de la subcarpeta «node_modules»:

Descarga de las dependencias, librerías adicionales con Node.js

Ejecutar JavaScript con Node.js

Una vez que hemos añadido las dependencias al fichero package.json y hemos descargado los ficheros .js necesarios para estas dependencias, como hemos indicado en pasos anteriores, podremos ejecutar nuestro script. Para ello usaremos el siguiente comando (siempre en el directorio donde tenemos el script .js, el fichero package.json y los ficheros de dependencias):

node actualizar.js

Nota importante: nuestro script no funcionará si no encuentra el fichero «actualizar.json» donde, como hemos explicado aquí, se especifican los orígenes y destinos de copia de cada carpeta y sus ficheros.

Un ejemplo de salida de la ejecución de nuestro script actualizar.js:

Ejecutar JavaScript con Node.js

Como vemos el script primero comprueba la disponibilidad de los equipos destino, haciendo un ping. Si no responde no intenta la copia, si responde intenta realizar la copia. Al finalizar el script muestra el resultado de la copia, los destinos que han tenido conectividad y los que no.

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

El proceso anterior puede ser un poco tedioso si queremos ejecutar nuestro JavaScript en otros equipos, tendríamos que instalar Node.js y usar el comando «node xxx.js» para ejecutar el script. Para evitar esto, existe una herramienta gratuita llamada JXcore que permite encapsular todo lo necesario en un ejecutable para que nuestro script puede ejecutarse en cualquier PC sin necesidad de instalar software adicional.

A continuación vamos a explicar cómo generar un fichero ejecutable a partir de un fichero JavaScript. Para ello necesitaremos tener instalado en nuestro equipo Node.js, como indicamos aquí y también necesitaremos JXcore. JXcore es una herramienta que a partir de Node.js permite generar un ejecutable embebido con todo lo necesario para que nuestra aplicación JavaScript pueda funcionar en cualquier PC sin necesidad de instalar Node.js ni ningún otro software. Con JXcore generaremos un .exe (ejecutable) a partir del .js (JavaScript).

Para descargar e instalar JXcore accederemos a la URL:

http://jxcore.com/downloads

En nuestro caso pulsaremos «Download» en Windows Setup (32/64/SM/V8):

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Guardaremos el archivo jx_winsetup.zip:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Lo descomprimiremos:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Ejecutaremos el fichero JXcore_setup.exe:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Se iniciará el asistente de instalación de JXcore, pulsaremos «Next»:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Leeremos los términos de liciencia, si estamos de acuerdo marcaremos «I accept the agreement» y pulsaremos «Next»:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Elegiremos la carpeta de instalación y pulsaremos «Next»:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

A continuación podremos elegir el ambiente de ejecución a instalar, en nuestro caso «V8 x64»:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Elegiremos el nombre para la carpeta que se creará en la barra de tareas y pulsaremos «Next»:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Es recomendable marcar la opción «Add application directory to environment PATH variable» para poder ejecutar el comando «jx» desde cualquier carpeta del equipo:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Comprobaremos las opciones elegidas, si son correctas puldaremos «Install» para instalar definitivamente JXcore:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Tras la instalación el asistente nos indicará que JXcore ha sido instalado correctamente. Pulsaremos «Finish»:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Una vez instalado JXcore ya podremos usar el comando «jx» para generar el ejecutable a partir del fichero JavaScritp y sus dependencias. Para ello abriremos una ventana de MS-DOS (como hemos explicado anteriormente) y accederemos a la carpeta donde tengamos el fichero de scritp JavaScript, en nuestro caso:

C:/AjpdSoft_JavaScript

Una vez en la carpeta ejecutaremos el siguiente comando:

jx package actualizar.js -native -add actualizar.js,node_modules

(teniendo en cuenta que en nuestro caso el fichero de script JavaScript se llama actualizar.js)

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Si todo es correcto y se ha generado el fichero ejecutable .exe a partir del .js nos mostrará el mensaje [OK] compiled file is ready (C:\AjpdSoft_JavaScript\actualizar.exe).

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Y podremos comprobar que en la carpeta del script JavaScript se ha generado el fichero actualizar.exe que ahora podrá funcionar en cualquier equipo sin necesidad de instalar Node.js ni de descargar las librerías adicionales pues van embebida en el ejecutable:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Y como decimos, podremos ejecutar el fichero actualizar.exe que se comportará como el fichero actualizar.js y sus librerías dependientes. En el caso de nuestro script de ejemplo podremos pasarle como parámetro al ejecutable el nombre del grupo de origen y destinos a utilizar que viene dado en el fichero actualizar.json:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

El contenido del fichero actaulizar.json de ejemplo del que ha leído la información el fichero actualizar.exe:

Cómo generar un ejecutable a partir de un JavaScript con JXcore y Node.js

Anexo

  • Salida comando npm init:
  • Fichero package.json creado por la herramienta npm:
  • Salida comando npm install colors pad path bluebird fs ping-bluebird collections mkdirp-then –save:
  • Resultado ejecución comando jx package actualizar.js -native -add actualizar.js,node_modules: