Desde su inicio, nadie ha considerado a JavaScript como un lenguaje de programación. En la era de la Web 1.0, este lenguaje de secuencias de comandos se utilizó principalmente para la verificación de formularios y los efectos especiales de la página web. No fue hasta la era web 2.0 que los ingenieros frontales lo usaron para mejorar en gran medida la experiencia del usuario en la página web que JS fue ampliamente valorado. A medida que JS se vuelve cada vez más popular, sufre aproximadamente cambios en la biblioteca de herramientas, la biblioteca de componentes, el marco frontal y las aplicaciones frontales. JavaScript carece inherentemente de una característica: módulos, y la aparición de la especificación CommonJS compensa esta deficiencia. Este artículo presentará la especificación CommonJS y el mecanismo del módulo de nodo.
En otros idiomas de alto nivel, Java tiene archivos de clase, Python tiene un mecanismo de importación y PHP ha incluido y requiere. La forma en que JS presenta código a través de la etiqueta <Script> parece desordenada. En el pasado, las personas tenían que usar espacios de nombres y otros métodos para restringir artificialmente el código. No fue hasta que surgió la especificación CommonJS que JavaScript front-end y back-end pudo lograr una gran unidad. Node toma prestado la especificación de módulos de CommonJS para implementar un sistema de módulos muy fácil de usar.
1. Especificación del módulo CommonJS
La especificación del módulo CommonJS se divide en 3 partes:
1). Referencia del módulo: introduzca la API de un módulo en el contexto actual a través del método requerir () y pase en un identificador de módulo, como var math = require ('math');
2). Definición del módulo: Exportar los métodos o variables del módulo actual a través del objeto Exports. También hay un objeto de módulo en el módulo, y las exportaciones son en realidad el atributo del módulo. En el nodo, un archivo es un módulo, y las "variables globales" en el módulo son invisibles para el mundo exterior. Solo los atributos montados en las exportaciones son públicos, como exports.Add = function () {}; exports.pi = 3.1415926;
3). ID de módulo: en realidad es el parámetro que se le pasa a requerir (). Por ejemplo, las 'matemáticas' mencionadas anteriormente, debe ser una cadena que se ajuste a la nomenclatura del camello, o una ruta relativa o absoluta que comienza con ". ".." No puede tener sufijo de nombre de archivo ".js"
2. Proceso de implementación del módulo de nodo
En el nodo, los módulos se dividen en dos categorías: una es el módulo central proporcionado por el propio nodo, y el otro es el módulo de archivo escrito por el propio usuario. Algunos de los módulos centrales se compilan en archivos binarios durante la compilación del código fuente del nodo. Cuando se inicia el nodo, el módulo de núcleo se carga directamente en la memoria, por lo que su velocidad de carga es la más rápida. El módulo de archivo se carga dinámicamente en tiempo de ejecución y requiere tres pasos: análisis de ruta, ubicación del archivo y compilación y ejecución. Tenga en cuenta que los cachés de nodo introdujeron módulos para reducir la sobrecarga durante la introducción secundaria y adopta la estrategia más preferida para la carga secundaria del mismo módulo.
2.1 Análisis de ruta
El análisis de ruta analiza principalmente los identificadores del módulo mencionados anteriormente, que se dividen principalmente en las siguientes categorías:
1) módulos centrales, como http, fs, ruta, etc.
2) Módulo de archivo de ruta relativa que comienza con. o .
3) Módulo de archivo de ruta absoluta que comienza con /
4) Módulo de archivo personalizado, que puede ser en forma de un archivo o paquete. El nodo intentará encontrar el archivo de destino uno por uno de acuerdo con el módulo de matriz de ruta del módulo.
2.2 Ubicación del archivo
Según el análisis de ruta, los siguientes detalles deben recibir atención a:
1) Análisis de extensión de archivo: dado que la especificación CommonJS permite que los identificadores del módulo no se completen, el nodo intentará en orden de .js, .json y .node
2) Análisis y paquete del directorio: si no se encuentra ningún archivo correspondiente después del análisis de extensión de archivo anterior, pero se obtiene un directorio, el nodo tratará el directorio como un paquete.
2.3 compilación y ejecución
Después de localizar el archivo específico, Node creará un nuevo objeto de módulo, cargará y compilará de acuerdo con la ruta. Para diferentes extensiones, el método de carga es diferente:
1) Archivo .js: lea el archivo sincrónicamente a través del módulo FS y compilarlo y ejecutarlo
2) .Node Archivo: Este es un archivo de extensión escrito en C/C ++, cargado a través del método dlopen ()
3) Archivo .json: lea el archivo sincrónicamente a través del módulo FS y use json.parse () para analizar y devolver el resultado
4) Otros archivos de extensión: se cargan como archivos .js
Sabemos que cada archivo de módulo tiene tres variables: requerir, exportar y módulo de forma predeterminada. Incluso en el documento de la API de nodo, sabemos que cada módulo también tiene dos variables: nombre de archivo y nombre de Dirname. ¿De dónde vienen? ¿Cómo logra el módulo del nodo que las "variables globales" declaradas no contaminarán otros módulos? De hecho, Node envolverá el contenido del archivo al principio y finalizará durante la compilación del módulo JS. Aquí hay un ejemplo de un archivo js envuelto por cabeza y cola:
La copia del código es la siguiente:
(función (exporta, requerir, módulo, __filename, __Dirname) {
/* El medio es el contenido real del archivo js*/
var math = request ('Math');
exports.area = function (radio) {
return math.pi * radio * radio;
};
/* El contenido real del archivo JS termina*/
});
De esta manera, cada archivo de módulo es aislamiento con alcance, y las variables como requeridas, exportaciones, módulos, etc. también se inyectan en el contexto del módulo. Esta es la implementación de la especificación del módulo CommonJS de Node. El proceso de compilación del módulo C/C ++ y el módulo de núcleo de nodo es relativamente complicado, por lo que no lo repetiré nuevamente.
3. Pila de llamadas de módulo
Es necesario aclarar las relaciones de llamada de varios módulos en el nodo, como se muestra en la figura a continuación:
El módulo incorporado de C/C ++ es el módulo de nivel más bajo y pertenece al módulo de núcleo. Principalmente proporciona API para llamar a los módulos principales de JavaScript y los módulos de archivo JavaScript de terceros. De hecho, casi no hay contacto con tales módulos. Hay dos responsabilidades principales de los módulos de núcleo de JavaScript: una es servir como la capa de encapsulación y la capa de puente del módulo incorporado de C/C ++ para llamadas al módulo de archivo, y el otro es un módulo funcional puro que no necesita lidiar con la capa subyacente. Los módulos de archivo generalmente están escritos por terceros, incluidos los módulos de JavaScript ordinarios y los módulos de extensión C/C ++.
4. Paquete y NPM
4.1 Estructura del paquete
El paquete es esencialmente un archivo de archivo (generalmente .zip o .tar.gz), que se descomprime y se restaura a un directorio después de la instalación. La especificación del paquete CommonJS consta de dos partes: estructura del paquete y archivo de descripción del paquete. Una estructura de paquete que cumple completamente con la especificación CommonJS debe contener los siguientes archivos:
1) .package.json: archivo de descripción del paquete
2) .Bin: el directorio donde se almacenan archivos binarios ejecutables
3) .lib: el directorio donde se almacena el código JavaScript
4) .doc: el directorio donde se almacena el documento
5). Prueba: el directorio donde se almacenan los casos de prueba unitaria
4.2 Archivo de descripción del paquete
El archivo de descripción del paquete es un archivo json: paquete.json, ubicado en el directorio raíz del paquete, es una parte importante del paquete y se utiliza para describir la información general del paquete. Todos los comportamientos de los NPM que se mencionarán más adelante están estrechamente relacionados con los campos de este archivo. A continuación, utilizaremos el archivo Packle.json de un proyecto Web Framework Express bien conocido como ejemplo para ilustrar el significado de algunos campos comúnmente utilizados.
1). Nombre: nombre del paquete
2). Descripción: Introducción al paquete
3) .versión: el número de versión debe cumplir con el "control semántico de versiones", consulte http://semver.org/
4) .ependencias: use la lista de paquetes en los que el paquete actual debe depender. Esta propiedad es muy importante. NPM cargará automáticamente el paquete dependiente a través de esta propiedad
5). Repositorios: Lista de ubicaciones para alojamiento del código fuente
El uso de otros campos se puede referir al paquete NPM.
4.3 Funciones comunes de NPM
NPM (administrador de paquetes de nodo), comúnmente conocido como Node Package Manager. Su función principal es administrar paquetes de nodos, que incluyen: instalación, desinstalar, actualizar, ver, buscar, publicar, etc.
4.3.1 Instalación del paquete NPM
Hay dos tipos de instalación de paquetes de nodos: instalación local e instalación global. La diferencia entre los dos es la siguiente:
1). Instalación local NPM Install <Cauppacy-Name>: El paquete se descargará en el directorio actual y solo se puede usar en el directorio actual.
2). Instalación global NPM Install -g <Apbackname>: el paquete se descargará a un directorio de sistema específico, y el paquete instalado se puede utilizar en todos los directorios.
4.3.2 Gestión de paquetes de NPM
La siguiente es una lista de comandos de gestión de paquetes de uso común que utilizan Grunt-Cli (herramienta de línea de comandos Grunt) como ejemplo:
1) .NPM Instalar: Instale todos los paquetes declarados por los campos de dependencias y Devdependencies del archivo paquete.json
2) .NPM Instale [email protected]: Instale la versión específica de Grunt-Cli
3) .NPM Instale Grunt-Contrib-Copy --save: instale Grunt-Contrib-Copy y guarde la dependencia en el archivo Packle.json
4) .npm desinstalar grunt-cli: paquete de desinstalación
5) Lista de NPM: Verifique qué paquetes están instalados
6) .NPM Publicar <Pareta>: Publicar paquete