JavaScript es uno de los lenguajes de programación más utilizados del mundo. Es el lenguaje común en el mundo web y es utilizado por todos los navegadores. El nacimiento de JavaScript se remonta a la era de Netscape, y su contenido central se desarrolló apresuradamente para luchar contra Microsoft y participar en la feroz guerra del navegador en ese momento. Debido al lanzamiento prematuro, algunas de sus pobres características inevitablemente dieron como resultado.
Aunque su tiempo de desarrollo es corto, JavaScript todavía tiene muchas características potentes, excepto la característica de compartir un espacio de nombres global para cada script.
Una vez que la página web se carga con el código JavaScript, se inyecta en el espacio de nombres global y compartirá el mismo espacio de direcciones que todos los demás scripts cargados, lo que conducirá a muchos problemas de seguridad, conflictos y algunos problemas comunes, lo que hace que los errores sean difíciles de rastrear y difíciles de resolver.
Pero afortunadamente, Node ha establecido algunas especificaciones para JavaScript del lado del servidor y también implementa el estándar del módulo CommonJS. En este estándar, cada módulo tiene su propio contexto y se distingue de otros módulos. Esto significa que los módulos no contaminarán el alcance global, porque no existe el llamado alcance global, y los módulos no interferirán entre sí.
En este capítulo, aprenderemos sobre varios módulos diferentes y cómo cargarlos.
La división del código en una serie de módulos bien definidos puede ayudarlo a controlar su aplicación. A continuación aprenderemos cómo crear y usar sus propios módulos.
Aprenda cómo el nodo carga módulos
En el nodo, los módulos se pueden hacer referencia a través de rutas de archivo o nombres de módulos. Si se hace referencia a un módulo no básico por nombre, el nodo eventualmente aludará el nombre del módulo a la ruta del archivo del módulo correspondiente. Y esos módulos centrales que contienen funciones centrales se precargarán cuando comience el nodo.
Los módulos no básicos incluyen módulos de terceros instalados usando NPM (Node Package Manager), así como módulos locales creados por usted o sus colegas.
Cada módulo importado por el script actual expondrá un conjunto de API expuestas al programador. Antes de usar el módulo, debe usar la función Requerir para importarlo, así:
La copia del código es la siguiente:
var módulo = requirir ('módulo_name')
El código anterior importará un módulo llamado Module_Name. Puede ser un módulo de núcleo o un módulo instalado con NPM. La función Requerir devuelve un objeto que contiene todas las API públicas del módulo. Dependiendo del módulo, el objeto devuelto puede ser cualquier valor de JavaScript, puede ser una función o un objeto que contenga una serie de atributos (funciones, matrices o cualquier objeto JavaScript).
Módulo de exportación
El sistema del módulo CommonJS es la única forma de compartir objetos y funciones entre archivos en nodo. Para un programa muy complejo, debe reconstruir algunas clases, objetos o funciones en una serie de módulos reutilizables bien definidos. Para los usuarios del módulo, el módulo solo expone el código que especificó al mundo exterior.
En el siguiente ejemplo, comprenderá que en el nodo, los archivos y los módulos corresponden uno por uno. Creamos un archivo llamado circle.js, que solo exporta el constructor de círculo al exterior.
La copia del código es la siguiente:
círculo de funciones (x, y, r) {
función r_squared () {
return math.pow (r, 2);
}
área de funciones () {
return math.pi * r_squared ();
}
regreso {área: área};
}
módulo.exports = círculo;
Lo más importante en el código es la última línea, que define qué exporta el módulo al exterior. El módulo es una variable especial, que representa el módulo actual, y Module.Exports es un objeto exportado desde el módulo. Puede ser cualquier objeto. En este ejemplo, exportamos el constructor de círculo para que los usuarios del módulo puedan usar este módulo para crear instancias de círculo.
También puede exportar algunos objetos complejos, Module.Exports se inicializa en un objeto vacío y exporta cualquier cosa que desee exponer al mundo exterior como los atributos del objeto Module.Exports. Por ejemplo, diseñó un módulo que expone un conjunto de funciones al exterior:
La copia del código es la siguiente:
función prema () {
console.log ('a');
}
function printB () {
console.log ('b');
}
función printc () {
console.log ('c');
}
módulo.exports.printa = printa;
módulo.exports.printb = printb;
módulo.exports.pi = Math.pi;
Este módulo exporta dos funciones (printA e printb) y un número (PI), y el código de llamada se ve así:
La copia del código es la siguiente:
var mymodule2 = request ('./ mymodule2');
mymodule2.printa (); // -> A
mymodule2.printb (); // -> B
console.log (mymodule2.pi); // -> 3.141592653589793
Módulo de carga
Como se mencionó anteriormente, puede usar la función Requerir para cargar módulos, y no se preocupe que llamar a la necesidad en el código afectará el espacio de nombres global, porque no hay un concepto de espacio de nombres global en el nodo. Si el módulo existe sin ningún error de sintaxis o inicialización, la función Requerir devolverá el objeto del módulo y también puede asignar este objeto a cualquier variable local.
Hay varios tipos diferentes de módulos, que se pueden dividir aproximadamente en módulos centrales, módulos locales y módulos de terceros instalados a través de NPM. Según el tipo de módulo, hay varias formas de referirse a los módulos. Aprendamos sobre estos conocimientos a continuación.
Cargando el módulo de núcleo
El nodo tiene algunos módulos compilados en archivos binarios, llamados módulos centrales. No pueden ser referenciados por rutas y solo pueden usarse con nombres de módulos. El módulo central tiene la prioridad de carga más alta, e incluso si ya hay un módulo de terceros del mismo nombre, el módulo central se cargará primero.
Por ejemplo, si desea cargar y usar el módulo de núcleo HTTP, puede hacer esto:
La copia del código es la siguiente:
var http = require ('http');
Esto devolverá un objeto que contenga el módulo HTTP, que contiene las API de los módulos HTTP definidos en la documentación de la API del nodo.
Cargando el módulo de archivo
También puede usar rutas absolutas para cargar módulos desde el sistema de archivos:
La copia del código es la siguiente:
var mymodule = require ('/home/pedro/my_modules/my_module');
También puede usar una ruta relativa basada en el archivo actual:
La copia del código es la siguiente:
var mymodule = request ('../ my_modules/my_module');
var mymodule2 = require ('./ lib/my_module_2');
Presta atención al código anterior. Puede omitir la extensión del nombre del archivo. Si el nodo no puede encontrar este archivo, intentará agregar un sufijo JS para buscar nuevamente después del nombre del archivo (Nota del traductor: De hecho, además de JS, también buscará JSON y Node. Para más detalles, puede ver la documentación oficial del sitio web). Por lo tanto, si existe un archivo llamado my_module.js en el directorio actual, habrá dos métodos de carga:
La copia del código es la siguiente:
var mymodule = request ('./ my_module');
var mymodule = require ('./ my_module.js');
Cargando el módulo de directorio
También puede usar la ruta del directorio para cargar el módulo:
La copia del código es la siguiente:
var mymodule = require ('./ myModuledir');
Node asumirá que este directorio es un paquete de módulo e intentará buscar el archivo de definición del paquete paquete.json en este directorio.
Si no se encuentra, el nodo asumirá que el punto de entrada del paquete es el archivo index.js (nota del traductor: además de index.js, también buscará index.node, y el archivo .node es el paquete de extensión binaria de Node, consulte el documento oficial para obtener detalles). El código anterior es un ejemplo. Node intentará encontrar el archivo ./mymoduledir/index.js.
Por el contrario, si se encuentra el archivo paquete.json, el nodo intentará analizarlo y buscar el atributo principal en la definición del paquete, y luego use el valor del atributo principal como la ruta relativa del punto de entrada. En este ejemplo, si paquete.json se define de la siguiente manera:
La copia del código es la siguiente:
{
"Nombre": "MyModule",
"Main": "./lib/mymodule.js"
}
El nodo intentará cargar el archivo ./mymoduledir/lib/mymodule.js
Cargar desde el directorio Node_Modules
Si los parámetros de la función Requerir no son rutas relativas o nombres de módulos de núcleo, se buscará el nodo en el subdirectorio Node_Modules del directorio actual. Por ejemplo, en el siguiente código, Node intentará encontrar el archivo./node_modules/mymodule.js:
La copia del código es la siguiente:
var mymodule = require ('mymodule.js');
Si no se encuentra, el nodo continuará buscando en la carpeta Node_Modules del directorio superior. Si no se encuentra, continúe buscando en el directorio superior hasta que se encuentre el módulo correspondiente o se alcanza el directorio raíz.
Puede usar esta función para administrar el contenido o módulos del directorio Node_Modules, pero es mejor entregar las tareas de administración del módulo al NPM (ver Capítulo 1). El directorio Node_Modules local es la ubicación predeterminada para el módulo de instalación de NPM. Este diseño asocia el nodo y NPM juntos. Por lo general, como desarrollador, no tiene que preocuparse demasiado por esta característica. Simplemente puede instalar, actualizar y eliminar paquetes con NPM, lo que lo ayudará a mantener el directorio Node_Modules.
Módulo de caché
El módulo se almacenará en caché después de la primera carga exitosa, es decir, si el nombre del módulo se resuelve a la misma ruta del archivo, entonces cada llamada para requerir ('myModule') devolverá exactamente el mismo módulo.
Por ejemplo, hay un módulo llamado my_module.js que contiene el siguiente contenido:
La copia del código es la siguiente:
console.log ('módulo my_module inicializando ...');
módulo.exports = function () {
console.log ('¡Hola!');
};
console.log ('my_module inicializado.');
Luego use el siguiente código para cargar el módulo:
La copia del código es la siguiente:
var myModuleInstance1 = request ('./ my_module');
Produce la siguiente salida:
La copia del código es la siguiente:
módulo my_module inicializando ...
my_module inicializado
Si lo importamos dos veces:
La copia del código es la siguiente:
var myModuleInstance1 = request ('./ my_module');
var mymoduleInstance2 = request ('./ my_module');
La salida sigue siendo:
La copia del código es la siguiente:
módulo my_module inicializando ...
my_module inicializado
Es decir, el código de inicialización del módulo se ejecuta solo una vez. Cuando crea su propio módulo, si el código de inicialización del módulo contiene código que puede tener efectos secundarios, debe prestar especial atención a esta característica.
resumen
Node canceló el alcance global predeterminado de JavaScript y, en su lugar, adoptó el sistema de módulos CommonJS, para que pueda organizar mejor su código y evitar muchos problemas y errores de seguridad. Puede usar la función Requerir para cargar módulos centrales, módulos de terceros o cargar sus propios módulos de archivos y directorios.
También puede usar rutas relativas o absolutas para cargar módulos no básicos. Si coloca el módulo en el directorio Node_Modules o para los módulos instalados con NPM, también puede usar directamente el nombre del módulo para cargar.
Nota del traductor:
Se recomienda que los lectores lean los capítulos del módulo del documento oficial. Personalmente siento que es más claro que el autor. Se ha conectado un ejemplo muy representativo, que será de gran ayuda para comprender la carga del módulo de nodo. También se cita lo siguiente:
La copia del código es la siguiente:
Use requerir (x) para cargar módulos en la ruta y
1. Si x es el módulo central,
a. Cargue y devuelva el módulo de núcleo
b. Fin
2. Si x comienza con './' o '/' o '../
a. Load_as_file (y + x)
b. Load_as_directory (y + x)
3. Load_node_modules (x, dirname (y))
4. Lanza una excepción: "No encontrado"
Load_as_file (x)
1. Si x es un archivo, cargue X como un script de JavaScript y finalice después de cargar
2. Si X.JS es un archivo, cargue X.JS como un script de JavaScript y finalice después de cargar
3. Si X.Node es un archivo, cargue X.Node como complemento binario de nodo y finalice después de la carga.
Load_as_directory (x)
1. Si existe el archivo x/paquete.json,
a. Parses x/paquete.json y encuentre el campo "principal".
b. También m = x + (valor del campo principal)
do. Load_as_file (m)
2. Si el archivo x/index.js existe, cargue x/index.js como un script JavaScript y finalice después de la carga.
3. Si el archivo x/index.node existe, cargue x/index.node como complemento binario de nodo y finalice después de la carga.
Load_node_modules (x, inicio)
1. También dirs = node_modules_paths (inicio)
2. Haga las siguientes operaciones para cada directorio Dir en Dirs:
a. Load_as_file (dir/x)
b. Load_as_directory (dir/x)
Node_modules_path (inicio)
1. También piezas = división de ruta (inicio)
2. También root = índice de primera instancia de "node_modules" en partes, o 0
3. También i = recuento de piezas - 1
4. También dirs = []
5. Mientras i> root,
a. Si las partes [i] = "node_modules", entonces la operación de seguimiento continuará, de lo contrario el siguiente bucle
do. Dir = ruta unión (piezas [0 .. i] + "node_modules")
b. Dirs = Dirs + Dir
do. También i = i - 1
6. Vuelva a los directivos