Antes de que se propusiera la especificación CommonJs, Javascript no tenía un sistema de módulos, lo que significaba que nos resultaba difícil desarrollar aplicaciones a gran escala porque la organización del código sería más difícil.
En primer lugar, CommonJS no es exclusivo de Node. CommonJS es una especificación de módulo que define cómo hacer referencia y exportar módulos. Nodejs solo implementa esta especificación. La especificación del módulo CommonJS se divide principalmente en tres partes: referencia del módulo, definición del módulo e identificación del módulo. .
Referencia del módulo
La referencia del módulo significa que podemos introducir otros módulos a través de require
.
const {añadir} = requerir('./añadir'); const resultado = add(1,2);
Módulo define
un archivo como un módulo, y el módulo proporcionará dos variables, a saber, módulo y exportaciones. módulo es el módulo actual en sí, exportaciones es el contenido que se va a exportar y exportaciones es un atributo del módulo, es decir, exportaciones es module.exports. El contenido importado por otros módulos a través de require es el contenido de module.exports.
// agregar.js exportaciones.add = (a, b) => { devolver a + b; }
Identificación del módulo
La identificación del módulo es el contenido en require. Por ejemplo, require('./add')
, luego la identificación del módulo es ./add
.
El mecanismo de importación y exportación de módulos creado a través de CommonJS permite a los usuarios crear fácilmente aplicaciones a gran escala sin tener que considerar la contaminación variable.
Implementación del módulo de nodo
Node implementa la especificación CommonJs y agrega algunas características que necesita. Node hace principalmente las siguientes tres cosas para implementar la especificación CommonJs:
Posicionamiento del archivo de
análisis de ruta
, compilación y ejecución del
análisis de ruta
Cuando se ejecuta require (), el parámetro recibido por require es el identificador del módulo y el nodo realiza el análisis de ruta a través del identificador del módulo. El propósito del análisis de ruta es encontrar la ruta donde se encuentra este módulo a través del identificador del módulo. En primer lugar, los módulos de nodo se dividen en dos categorías: módulos centrales y módulos de archivos. El módulo principal es el módulo que viene con el nodo y el módulo de archivo es el módulo escrito por el usuario. Al mismo tiempo, los módulos de archivos se dividen en módulos de archivos en forma de rutas relativas, módulos de archivos en forma de rutas absolutas y módulos de archivos en forma de no rutas (como express).
Cuando el nodo encuentra un módulo de archivo, compilará, ejecutará y almacenará en caché el módulo. El principio general es utilizar la ruta completa del módulo como clave y el contenido compilado como valor. Esto no será necesario cuando se introduzca el módulo. por segunda vez, luego realice el análisis de ruta, la ubicación del archivo, la compilación y la ejecución de estos pasos. El contenido compilado se puede leer directamente desde el caché.
//Diagrama del módulo de caché: const módulo en caché = { '/Usr/file/src/add.js': 'Contenido compilado de add.js', 'http': 'Contenido compilado del módulo http que viene con Node', 'express': 'Contenido compilado del módulo de archivo personalizado sin ruta express' //... }
Cuando desee encontrar el módulo importado por require, el orden de búsqueda del módulo es verificar primero si el módulo ya está en el caché. Si no está en el caché, luego verifique el módulo principal y luego busque. el módulo de archivos. Entre ellos, los módulos de archivos en forma de rutas son más fáciles de encontrar. La ruta completa del archivo se puede obtener en función de la ruta relativa o absoluta. Es relativamente problemático encontrar módulos de archivos personalizados en formato sin ruta. Node buscará el archivo en la carpeta node_modules.
¿Dónde está el directorio node_modules? Por ejemplo, el archivo que estamos ejecutando actualmente es /Usr/file/index.js
; * /Usr/file/index.js; */ const {agregar} = requerir('agregar'); const result = add(1, 2);
En este módulo, hemos introducido un módulo adicional. Este complemento no es un módulo principal ni un módulo de archivo en forma de ruta.
El módulo tiene un atributo de ruta. La ruta para encontrar el módulo agregado está en el atributo de rutas. Podemos escribir este atributo para echar un vistazo:
/**. * /Usr/file/index.js; */ console.log(module.paths);
Podemos imprimir el valor de las rutas ejecutando el nodo index.js en el directorio de archivos. El valor en las rutas es una matriz, como sigue:
[ '/usr/archivo/node_modules', '/Usr/nodo_modules', '/módulos_nodo', ]
Es decir, Node buscará secuencialmente desde el directorio anterior para ver si contiene el módulo agregado. El principio es similar a la cadena de prototipos. Primero, comience a buscar en la carpeta node_modules en el directorio del mismo nivel que el archivo ejecutado actualmente. Si el directorio node_modules no se encuentra o no existe, continúe buscando hasta el nivel superior.
El análisis de rutade ubicación de archivos
y la ubicación de archivos se utilizan juntos. El identificador de archivo puede no tener un sufijo, o se puede encontrar un directorio o paquete mediante el análisis de ruta. En este caso, la localización del archivo específico requiere algún procesamiento adicional.
Análisis de extensión de archivo
const { add } = require('./add');
Por ejemplo, en el código anterior, el identificador de archivo no tiene una extensión. En este momento, el nodo buscará la existencia de .js, .json. y .node en secuencia.
El análisis de directorios y paquetes
es el mismo que el código anterior. Lo que se encuentra a través de ./add
puede no ser un archivo, pero puede ser un directorio o paquete (juzgue si es un directorio o un paquete juzgando si hay un paquete). json en la carpeta Agregar). En este momento, los pasos para el posicionamiento del archivo son los siguientes:
Si no hay un campo principal en package.json, el índice también se usará como un archivo y luego se realizará un análisis de extensión para encontrar el archivo con el sufijo correspondiente. .
Compilación de módulos
Los principales módulos que encontramos en el desarrollo son los módulos json y los módulos js.
compilación del módulo json
Cuando necesitamos un módulo json, Node realmente nos ayudará a usar fs.readFilcSync para leer el archivo json correspondiente, obtener la cadena json y luego llamar a JSON.parse para analizar y obtener el objeto json y luego asignarlo a el módulo exporta y luego dale a require.
Compilación del módulo js
Cuando necesitamos un módulo js, como
// index.js const {agregar} = requerir('./agregar');
// agregar.js exportaciones.add = (a, b) => { devolver a + b; } ¿
Qué pasó en este momento? ¿Por qué podemos usar el módulo de variables, exportar y requerir directamente en el módulo? Esto se debe a que Node envuelve el contenido del módulo primero y último al compilar el módulo js.
Por ejemplo, el módulo add.js se empaquetará en una estructura similar a esta cuando realmente se compile:
(función(require, exports, module) { exportaciones.add = (a, b) => { devolver a + b; } devolver módulo.exportaciones; })(require, module.exports, module)
Es decir, el archivo js que escribimos se empaquetará en una función. Lo que escribimos es solo el contenido de esta función, y el proceso de empaquetado posterior de Node está oculto para nosotros. Esta función admite el paso de algunos parámetros, incluidos require, exports y module.
Una vez compilado el archivo js, el archivo se ejecutará. Node pasará los parámetros correspondientes a esta función y luego la ejecutará y devolverá el valor module.exports a la función requerida.
Lo anterior es el proceso básico para que Node implemente las especificaciones de CommonJs.