Pregunta ¿Cuál es el propósito del módulo Node.js module.exports y cómo lo usas?


¿Cuál es el propósito del módulo Node.js module.exports y cómo lo usas?

Parece que no puedo encontrar ninguna información sobre esto, pero parece ser una parte bastante importante de Node.js, ya que a menudo lo veo en el código fuente.

De acuerdo con la Documentación de Node.js:

módulo 

Una referencia a la corriente    module. En particular module.exports   es lo mismo que el objeto de exportación. Ver    src/node.js para más información.

Pero esto realmente no ayuda.

¿Qué es exactamente? module.exports hacer, y ¿qué sería un simple ejemplo?


1237
2018-03-15 11:56


origen


Respuestas:


module.exports es el objeto que en realidad se devuelve como resultado de un require llamada.

los exports la variable se establece inicialmente en ese mismo objeto (es decir, es un "alias" abreviado), por lo que en el código del módulo generalmente escribiría algo como esto:

var myFunc1 = function() { ... };
var myFunc2 = function() { ... };
exports.myFunc1 = myFunc1;
exports.myFunc2 = myFunc2;

para exportar (o "exponer") las funciones internas myFunc1 y myFunc2.

Y en el código de llamada usarías:

var m = require('./mymodule');
m.myFunc1();

donde la última línea muestra cómo el resultado de require es (generalmente) solo un objeto simple cuyas propiedades se pueden acceder.

NB: si sobrescribe exports entonces ya no se referirá a module.exports. Entonces, si desea asignar un objeto nuevo (o una referencia de función) a exports entonces también deberías asignar ese nuevo objeto a module.exports


Vale la pena señalar que el nombre agregado a la exports objeto no tiene que ser el mismo que el nombre del alcance interno del módulo para el valor que está agregando, por lo que podría tener:

var myVeryLongInternalName = function() { ... };
exports.shortName = myVeryLongInternalName;
// add other objects, functions, as required

seguido por:

var m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName

1452
2018-03-15 12:00



Esto ya ha sido respondido, pero quería agregar algunas aclaraciones ...

Puedes usar ambos exports y module.exports para importar código en su aplicación de esta manera:

var mycode = require('./path/to/mycode');

El caso de uso básico que verás (por ejemplo, en el código de ejemplo de ExpressJS) es que estableces propiedades en exports objeto en un archivo .js que luego importa usando require()

Entonces, en un simple ejemplo de conteo, podrías tener:

(counter.js):

var count = 1;

exports.increment = function() {
    count++;
};

exports.getCount = function() {
    return count;
};

... luego en su aplicación (web.js, o realmente cualquier otro archivo .js):

var counting = require('./counter.js');

console.log(counting.getCount()); // 1
counting.increment();
console.log(counting.getCount()); // 2

En términos simples, puede pensar en los archivos necesarios como funciones que devuelven un solo objeto, y puede agregar propiedades (cadenas, números, matrices, funciones, cualquier cosa) al objeto que se devuelve configurándolos en exports.

A veces querrás que el objeto devuelto de un require() llamada para ser una función a la que puede llamar, en lugar de solo un objeto con propiedades. En ese caso, también necesita establecer module.exports, Me gusta esto:

(sayhello.js):

module.exports = exports = function() {
    console.log("Hello World!");
};

(app.js):

var sayHello = require('./sayhello.js');
sayHello(); // "Hello World!"

La diferencia entre exportaciones y module.exports se explica mejor en esta respuesta aquí.


194
2017-10-16 05:03



Tenga en cuenta que el mecanismo del módulo NodeJS se basa en CommonJS módulos que son compatibles con muchas otras implementaciones como RequireJS, pero también SproutCore, CouchDB, Wakanda, OrientDB, ArangoDB, RingoJS, TeaJS, SilkJS, curl.js, o incluso Adobe Photoshop (vía PSLib) Puede encontrar la lista completa de implementaciones conocidas aquí.

A menos que su módulo use características o módulos específicos de nodo, le recomiendo que use exports en lugar de module.exports  que no es parte de la norma CommonJSy, en general, no es compatible con otras implementaciones.

Otra característica específica de NodeJS es cuando asigna una referencia a un nuevo objeto para exports en lugar de solo agregarle propiedades y métodos, como en el último ejemplo proporcionado por Jed Watson en este hilo. Desanimaría personalmente esta práctica ya que rompe el soporte de referencia circular del mecanismo de módulos CommonJS. Entonces no es compatible con todas las implementaciones y el ejemplo de Jed se debe escribir de esta manera (o uno similar) para proporcionar un módulo más universal:

(sayhello.js):

exports.run = function() {
    console.log("Hello World!");
}

(app.js):

var sayHello = require('./sayhello');
sayHello.run(); // "Hello World!"

O usando las características de ES6

(sayhello.js):

Object.assign(exports, {
    // Put all your public API here
    sayhello() {
        console.log("Hello World!");
    }
});

(app.js):

const { sayHello } = require('./sayhello');
sayHello(); // "Hello World!"

PD: parece que Appcelerator también implementa módulos CommonJS, pero sin el soporte de referencia circular (ver: Módulos Appcelerator y CommonJS (almacenamiento en caché y referencias circulares))


53
2018-01-20 12:35



Algunas cosas que debe tener cuidado si asigna una referencia a un nuevo objeto para exports y / o modules.exports:

1. Todas las propiedades / métodos previamente vinculados al original exports o module.exports Por supuesto, se pierden porque el objeto exportado ahora hará referencia a otro nuevo

Este es obvio, pero si agrega un método exportado al comienzo de un módulo existente, asegúrese de que el objeto exportado nativo no haga referencia a otro objeto al final

exports.method1 = function () {}; // exposed to the original exported object
exports.method2 = function () {}; // exposed to the original exported object

module.exports.method3 = function () {}; // exposed with method1 & method2

var otherAPI = {
    // some properties and/or methods
}

exports = otherAPI; // replace the original API (works also with module.exports)

2. En caso de que uno de exports o module.exports referencia un nuevo valor, ya no hacen referencia al mismo objeto

exports = function AConstructor() {}; // override the original exported object
exports.method2 = function () {}; // exposed to the new exported object

// method added to the original exports object which not exposed any more
module.exports.method3 = function () {}; 

3. Consecuencia difícil. Si cambia la referencia a ambos exports y module.exports, es difícil decir qué API está expuesta (parece que module.exports gana)

// override the original exported object
module.exports = function AConstructor() {};

// try to override the original exported object
// but module.exports will be exposed instead
exports = function AnotherConstructor() {}; 

31
2018-01-25 09:02



la propiedad module.exports o el objeto export permite que un módulo seleccione qué se debe compartir con la aplicación

enter image description here

Tengo un video en module_export disponible aquí


23
2017-09-03 19:01



Al dividir el código de su programa en varios archivos, module.exports se usa para publicar variables y funciones al consumidor de un módulo. los require() llamar a su archivo de origen se reemplaza con el correspondiente module.exports cargado desde el módulo.

Recuerde cuando escribe módulos

  • Las cargas del módulo están en caché, solo la llamada inicial evalúa JavaScript.
  • Es posible usar variables locales y funciones dentro de un módulo, no todo se debe exportar.
  • los module.exports objeto también está disponible como exports taquigrafía. Pero al devolver una función única, siempre use module.exports.

module exports diagram

De acuerdo a: "Módulos Parte 2 - Módulos de escritura".


17
2017-08-06 21:05



el enlace de referencia es así:

exports = module.exports = function(){
    //....
}

las propiedades de exports o module.exports , como funciones o variables, estarán expuestos fuera

hay algo que debes prestar más atención: no lo hagas override exportaciones.

por qué ?

como las exportaciones son solo la referencia de module.exports, puede agregar las propiedades a las exportaciones, pero si anula las exportaciones, el enlace de referencia se romperá.

buen ejemplo :

exports.name = 'william';

exports.getName = function(){
   console.log(this.name);
}

mal ejemplo :

exports = 'william';

exports = function(){
     //...
}

Si solo desea exponer solo una función o variable, haga lo siguiente:

// test.js
var name = 'william';

module.exports = function(){
    console.log(name);
}   

// index.js
var test = require('./test');
test();

este módulo solo expuso una función y la propiedad del nombre es privada para el exterior.


8
2018-04-18 00:53



Hay algunos módulos predeterminados o existentes en node.js cuando descarga e instala node.js como http, sys etc.

Como ya están en node.js, cuando queremos usar estos módulos, básicamente nos gusta importar módulos, ¿pero por qué? porque ya están presentes en el node.js. Importar es como tomarlos de node.js y ponerlos en su programa. Y luego usarlos.

Mientras Exportaciones es exactamente lo contrario, está creando el módulo que desea, digamos el módulo addition.js y colocando ese módulo en node.js, lo hace exportándolo.

Antes de escribir algo aquí, recuerda, module.exports.addition Two es lo mismo que exports.addition Two


4
2017-07-27 20:49