work unexpected nodejs node modules instead how exports es6 doesn javascript node.js commonjs

javascript - unexpected - módulo.exportaciones vs exportaciones en Node.js



node js unexpected identifier (20)

por qué ambos se utilizan aquí

Creo que solo quieren dejar en claro que el module.exports . exports , exports y nano apuntan a la misma función, permitiéndole usar cualquiera de las dos variables para llamar a la función dentro del archivo. nano proporciona algún contexto a lo que hace la función.

exports no se exportarán (solo module.exports hará el module.exports ), entonces, ¿por qué molestarse en sobrescribir eso también?

La compensación de verbosidad limita el riesgo de futuros errores, como el uso de exports lugar de module.exports dentro del archivo. También proporciona una aclaración de que el module.exports y exports de hecho están apuntando al mismo valor.

module.exports vs exports

Mientras no reasigne module.exports o exports (y en su lugar agregue valores al objeto al que ambos se refieren), no tendrá ningún problema y puede usar las exports forma segura para ser más conciso.

Al asignar cualquiera de ellos a un no-objeto, ahora están apuntando a diferentes lugares que pueden ser confusos, a menos que intencionalmente desee que el module.exports sea ​​algo específico (como una función).

Configurar las exports a un no-objeto no tiene mucho sentido, ya que tendrá que configurar module.exports = exports al final para poder usarlo en otros archivos.

let module = { exports: {} }; let exports = module.exports; exports.msg = ''hi''; console.log(module.exports === exports); // true exports = ''yo''; console.log(module.exports === exports); // false exports = module.exports; console.log(module.exports === exports); // true module.exports = ''hello''; console.log(module.exports === exports); // false module.exports = exports; console.log(module.exports === exports); // true

¿Por qué asignar module.exports a una función?

¡Más conciso! Compara cuánto más corto es el segundo ejemplo:

helloWorld1.js: module.exports.hello = () => console.log(''hello world'');

app1.js: let sayHello = require(''./helloWorld1''); sayHello.hello; // hello world let sayHello = require(''./helloWorld1''); sayHello.hello; // hello world

helloWorld2.js: module.exports = () => console.log(''hello world'');

app2.js: let sayHello = require(''./helloWorld2''); sayHello; // hello world let sayHello = require(''./helloWorld2''); sayHello; // hello world

He encontrado el siguiente contrato en un módulo Node.js:

module.exports = exports = nano = function database_module(cfg) {...}

Me pregunto module.exports las diferencias entre module.exports exports y exports y por qué se utilizan aquí.


JavaScript pasa objetos por copia de una referencia

Es una diferencia sutil que ver con la forma en que los objetos se pasan por referencia en JavaScript.

exports y module.exports apuntan al mismo objeto. exports es una variable y module.exports es un atributo del objeto de módulo.

Digamos que escribo algo como esto:

exports = {a:1}; module.exports = {b:12};

exports y module.exports ahora apuntan a diferentes objetos. La modificación de las exportaciones ya no modifica module.exports.

Cuando la función de importación inspecciona module.exports se obtiene {b:12}


  1. Tanto el module.exports exports como los de exports apuntan a la misma function database_module(cfg) {...} .

    1| var a, b; 2| a = b = function() { console.log("Old"); }; 3| b = function() { console.log("New"); }; 4| 5| a(); // "Old" 6| b(); // "New"

    Puede cambiar b en la línea 3 a a , la salida es inversa. La conclusión es:

    b son independientes.

  2. Entonces module.exports = exports = nano = function database_module(cfg) {...} es equivalente a:

    var f = function database_module(cfg) {...}; module.exports = f; exports = f;

    module.js que lo anterior es module.js , que es requerido por foo.js Los beneficios de module.exports = exports = nano = function database_module(cfg) {...} están claros ahora:

    • En foo.js , dado que module.exports es require(''./module.js'') :

      var output = require(''./modules.js'')();

    • En moduls.js : puede utilizar las exports lugar de module.exports .

Por lo tanto, estará contento si tanto las exports como el module.exports apuntan a lo mismo.


"Si desea que la raíz de la exportación de su módulo sea una función (como un constructor) o si desea exportar un objeto completo en una asignación en lugar de construirlo una propiedad a la vez, asígnelo a module.exports en lugar de exportaciones ". - http://nodejs.org/api/modules.html


1.exports -> use como utilidad singleton
2. módulo-exportaciones -> utilizar como objetos lógicos como servicio, modelo, etc.


A pesar de que la pregunta ha sido respondida y aceptada hace mucho tiempo, solo quiero compartir mis 2 centavos:

Puedes imaginar que al principio de tu archivo hay algo como (solo para explicación):

var module = new Module(...); var exports = module.exports;

Entonces, haga lo que haga, tenga en cuenta que el module.exports y NO exports se devolverán de su módulo cuando necesite ese módulo de otra parte.

Así que cuando haces algo como:

exports.a = function() { console.log("a"); } exports.b = function() { console.log("b"); }

También está agregando 2 funciones ''a'' y ''b'' al objeto en el que módulo.exporta puntos, por lo que el tipo del resultado devuelto será un object : { a: [Function], b: [Function] }

Por supuesto, este es el mismo resultado que obtendrá si está utilizando module.exports en este ejemplo en lugar de las exports .

Este es el caso en el que desea que sus module.exports se comporten como un contenedor de valores exportados. Mientras que, si solo desea exportar una función de constructor, hay algo que debe saber sobre el uso de module.exports o exports (recuerde nuevamente que module.exports se devolverá cuando necesite algo, no exportar).

module.exports = function Something() { console.log(''bla bla''); }

Ahora, typeof return results es ''function'' y puede solicitarlo e invocar inmediatamente como:
var x = require(''./file1.js'')(); Porque sobreescribes el resultado que regresa para ser una función.

Sin embargo, usando las exports no puedes usar algo como:

exports = function Something() { console.log(''bla bla''); } var x = require(''./file1.js'')(); //Error: require is not a function

Debido a que con las exports , la referencia ya no ''apunta'' al objeto donde module.exports puntos, por lo que ya no existe una relación entre exports y module.exports . En este caso, module.exports aún apunta al objeto vacío {} que se devolverá.

La respuesta aceptada de otro tema también debería ayudar: ¿Pasa Javascript por referencia?


Aquí está el resultado de

console.log("module:"); console.log(module); console.log("exports:"); console.log(exports); console.log("module.exports:"); console.log(module.exports);

También:

if(module.exports === exports){ console.log("YES"); }else{ console.log("NO"); } //YES

Nota: La especificación CommonJS solo permite el uso de la variable de exportaciones para exponer a los miembros públicos. Por lo tanto, el patrón de exportación nombrado es el único que es realmente compatible con la especificación CommonJS. El uso de module.exports es una extensión proporcionada por Node.js para admitir una gama más amplia de patrones de definición de módulos.


Aquí hay una buena descripción escrita sobre los módulos de nodo en node.js en el libro de acciones de la publicación Manning .
Lo que finalmente se exporta en su aplicación es module.exports.
Las exportaciones se configuran simplemente como una referencia global a module.exports , que inicialmente se define como un objeto vacío al que puede agregar propiedades. Así que exports.myFunc es solo una abreviatura de module.exports.myFunc .

Como resultado, si las exportaciones se configuran como cualquier otra cosa, rompe la referencia entre módulo.exportaciones y exportaciones . Debido a que module.exports es lo que realmente se exporta, las exportaciones ya no funcionarán como se esperaba, ya no hace referencia al módulo .exports . Si desea mantener ese enlace, puede hacer que las exportaciones de referencia de module.exports se realicen de la siguiente manera:

module.exports = exports = db;


Básicamente, la respuesta está en lo que realmente sucede cuando se requiere un módulo a través de require declaración de require . Suponiendo que esta es la primera vez que se requiere el módulo.

Por ejemplo:

var x = require(''file1.js'');

contenido de file1.js:

module.exports = ''123'';

Cuando se ejecuta la instrucción anterior, se crea un objeto de Module . Su función constructora es:

function Module(id, parent) { this.id = id; this.exports = {}; this.parent = parent; if (parent && parent.children) { parent.children.push(this); } this.filename = null; this.loaded = false; this.children = []; }

Como ves, cada objeto de módulo tiene una propiedad con nombre de exports . Esto es lo que finalmente se devuelve como parte de la require .

El siguiente paso para requerir es envolver el contenido de file1.js en una función anónima como la siguiente:

(function (exports, require, module, __filename, __dirname) { //contents from file1.js module.exports = ''123; });

Y esta función anónima se invoca de la siguiente manera, el module aquí se refiere al objeto de Module creado anteriormente.

(function (exports, require, module, __filename, __dirname) { //contents from file1.js module.exports = ''123; }) (module.exports,require, module, "path_to_file1.js","directory of the file1.js");

Como podemos ver dentro de la función, los argumentos de exports refieren a module.exports . En esencia, es una conveniencia proporcionada al programador de módulos.

Sin embargo esta conveniencia debe ser ejercitada con cuidado. En cualquier caso, si intenta asignar un nuevo objeto a las exportaciones, asegúrese de hacerlo de esta manera.

exports = module.exports = {};

Si lo hacemos de la manera incorrecta , module.exports seguirá apuntando al objeto creado como parte de la instancia del módulo.

exports = {};

Como resultado, agregar algo al objeto de exportaciones anterior no tendrá ningún efecto en el objeto module.exports y nada se exportará ni se devolverá como parte de require.


De los docs

La variable de exportación está disponible dentro del alcance a nivel de archivo de un módulo y se le asigna el valor de module.exports antes de que se evalúe el módulo.

Permite un acceso directo, por lo que module.exports.f = ... puede escribirse de manera más sucinta como exportaciones.f = .... Sin embargo, tenga en cuenta que como cualquier variable, si se asigna un nuevo valor a las exportaciones, es Ya no está vinculado a module.exports:

Es solo una variable que apunta a module.exports.


En el archivo node js module.js se usa para ejecutar el sistema de module.load. Cada vez que el nodo ejecuta un archivo, envuelve el contenido de su archivo js de la siguiente manera

''(function (exports, require, module, __filename, __dirname) {'',+ //your js file content ''/n});''

Debido a este ajuste dentro del código fuente de ur js, puede acceder a las exportaciones, los requisitos, el módulo, etc. Este enfoque se utiliza porque no hay otra forma de escribir las funciones en el archivo js a otro.

luego el nodo ejecuta esta función envuelta usando c ++. en ese momento se rellenará el objeto exportado que haya pasado a esta función.

Puedes ver dentro de esta función los parámetros de exportación y módulo. en realidad las exportaciones es un miembro público de la función constructor de módulos.

mira el siguiente código

Copia este código en b.js

console.log("module is "+Object.prototype.toString.call(module)); console.log("object.keys "+Object.keys(module)); console.log(module.exports); console.log(exports === module.exports); console.log("exports is "+Object.prototype.toString.call(exports)); console.log(''----------------------------------------------''); var foo = require(''a.js''); console.log("object.keys of foo: "+Object.keys(foo)); console.log(''name is ''+ foo); foo();

Copia este código a a.js

exports.name = ''hello''; module.exports.name = ''hi''; module.exports.age = 23; module.exports = function(){console.log(''function to module exports'')}; //exports = function(){console.log(''function to export'');}

ahora ejecuta el nodo

esta es la salida

module is [object Object] object.keys id,exports,parent,filename,loaded,children,paths {} true

exportaciones es [objeto objeto]

object.keys of foo: name is function () {console.log (''función a las exportaciones de módulos'')} función a las exportaciones de módulos

ahora elimine la línea comentada en a.js y comente la línea sobre esa línea y elimine la última línea de b.js y ejecute.

en javascript world no puede reasignar el objeto que pasó como parámetro, pero puede cambiar el miembro público de la función cuando el objeto de esa función se establece como un parámetro para otra función

recuerda

use module.exports on y solo si desea obtener una función cuando usa la palabra clave require. en el ejemplo anterior, var foo = require (a.js); Puedes ver que podemos llamar a foo como una función;

así es como lo explica la documentación del nodo "El sistema de Módulo crea el objeto de exportación. A veces esto no es aceptable, muchos quieren que su módulo sea una instancia de alguna clase. Para ello, asigne el objeto de exportación deseado a module.exports".


Esto muestra cómo require() funciona en su forma más simple, extraído de Eloquent JavaScript

Problema No es posible que un módulo exporte directamente un valor que no sea el objeto de exportación, como una función. Por ejemplo, un módulo podría querer exportar solo el constructor del tipo de objeto que define. En este momento, no puede hacerlo porque require siempre usa el objeto de exports que crea como el valor exportado.

Solución Proporcione módulos con otra variable, module , que es un objeto que tiene una propiedad que se exports . Esta propiedad apunta inicialmente al objeto vacío creado por require pero se puede sobrescribir con otro valor para exportar otra cosa.

function require(name) { if (name in require.cache) return require.cache[name]; var code = new Function("exports, module", readFile(name)); var exports = {}, module = {exports: exports}; code(exports, module); require.cache[name] = module.exports; return module.exports; } require.cache = Object.create(null);


He encontrado este enlace útil para responder a la pregunta anterior.

http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/

Para agregar a las otras publicaciones El sistema de módulos en el nodo hace

var exports = module.exports

Antes de ejecutar tu código. Entonces, cuando quieras exportar = foo, probablemente quieras hacer module.exports = exports = foo pero usar exports.foo = foo debería estar bien


Inicialmente, module.exports=exports , y la función require devuelve el objeto module.exports refiere.

si agregamos propiedades al objeto, digamos exports.a=1 , entonces module.exports y exportaciones aún se refieren al mismo objeto. Entonces, si llamamos a require y asignamos el módulo a una variable, entonces la variable tiene una propiedad a y su valor es 1;

Pero si anulamos uno de ellos, por ejemplo, exports=function(){} , ahora son diferentes : exportaciones se refieren a un nuevo objeto y module.exports se refieren al objeto original. Y si requerimos el archivo, no devolverá el nuevo objeto, ya que module.exports no se refiere al nuevo objeto.

Para mí, seguiré agregando nuevas propiedades, o las anularé a un nuevo objeto. Simplemente anular uno no es correcto. Y tenga en cuenta que module.exports es el verdadero jefe.


La configuración de module.exports permite que la función database_module se llame como una función cuando sea required . La simple configuración de las exports no permitiría exportar la función porque el nodo exporta las referencias del objeto module.exports . El siguiente código no permitiría al usuario llamar a la función.

módulo.js

Lo siguiente no funcionará.

exports = nano = function database_module(cfg) {return;}

Lo siguiente funcionará si se establece module.exports .

module.exports = exports = nano = function database_module(cfg) {return;}

consola

var func = require(''./module.js''); // the following line will **work** with module.exports func();

Básicamente, node.js no exporta el objeto que exports actualmente las referencias, sino que exporta las propiedades de lo que las exports originalmente hacen referencia. Aunque Node.js sí exporta las referencias del objeto module.exports , lo que le permite llamarlo como una función.

2da razón menos importante

Establecen tanto las exports module.exports como las exports para garantizar que las exports no module.exports referencia al objeto exportado anterior. Al configurar tanto las exports como las abreviaturas y evitar posibles errores más adelante en el futuro.

El uso de module.exports.prop = true exports.prop = true lugar de module.exports.prop = true guarda los caracteres y evita la confusión.


Pasé por algunas pruebas y creo que esto puede arrojar algo de luz sobre el tema ...

app.js :

var ... , routes = require(''./routes'') ...; ... console.log(''@routes'', routes); ...

Versiones de /routes/index.js :

exports = function fn(){}; // outputs "@routes {}" exports.fn = function fn(){}; // outputs "@routes { fn: [Function: fn] }" module.exports = function fn(){}; // outputs "@routes function fn(){}" module.exports.fn = function fn(){}; // outputs "@routes { fn: [Function: fn] }"

Incluso agregué nuevos archivos:

./routes/index.js :

module.exports = require(''./not-index.js''); module.exports = require(''./user.js'');

./routes/not-index.js :

exports = function fn(){};

./routes/user.js :

exports = function user(){};

Obtenemos la salida "@routes {}"

./routes/index.js :

module.exports.fn = require(''./not-index.js''); module.exports.user = require(''./user.js'');

./routes/not-index.js :

exports = function fn(){};

./routes/user.js :

exports = function user(){};

Obtenemos la salida "@routes {fn: {}, usuario: {}}"

./routes/index.js :

module.exports.fn = require(''./not-index.js''); module.exports.user = require(''./user.js'');

./routes/not-index.js :

exports.fn = function fn(){};

./routes/user.js :

exports.user = function user(){};

Obtenemos la salida "@routes {user: [Function: user]}" Si cambiamos user.js por { ThisLoadedLast: [Function: ThisLoadedLast] } , obtenemos la salida "@routes {ThisLoadedLast: [Function: ThisLoadedLast]} ".

Pero si modificamos ./routes/index.js ...

./routes/index.js :

module.exports.fn = require(''./not-index.js''); module.exports.ThisLoadedLast = require(''./user.js'');

./routes/not-index.js :

exports.fn = function fn(){};

./routes/user.js :

exports.ThisLoadedLast = function ThisLoadedLast(){};

... obtenemos "@routes {fn: {fn: [Función: fn]}, ThisLoadedLast: {ThisLoadedLast: [Function: ThisLoadedLast]}}"

Por lo tanto, sugiero usar siempre module.exports en las definiciones de sus módulos.

No entiendo completamente lo que está pasando internamente con Node, pero comente si puede darle más sentido a esto ya que estoy seguro de que esto ayuda.

- feliz codificacion


Solo hago algunas pruebas, resulta que, dentro del código del módulo de nodejs, debería algo como esto:

var module.exports = {}; var exports = module.exports;

asi que:

1:

exports = function(){}; // this will not work! as it make the exports to some other pointer module.exports = function(){}; // it works! cause finally nodejs make the module.exports to export.

2:

exports.abc = function(){}; // works! exports.efg = function(){}; // works!

3: pero, mientras que en este caso

module.exports = function(){}; // from now on we have to using module.exports to attach more stuff to exports. module.exports.a = ''value a''; // works exports.b = ''value b''; // the b will nerver be seen cause of the first line of code we have do it before (or later)


Vamos a crear un módulo de 2 maneras:

De una sola mano

var aa = { a: () => {return ''a''}, b: () => {return ''b''} } module.exports = aa;

Segunda vía

exports.a = () => {return ''a'';} exports.b = () => {return ''b'';}

Y así es como require () integrará el módulo.

Primera forma:

function require(){ module.exports = {}; var exports = module.exports; var aa = { a: () => {return ''a''}, b: () => {return ''b''} } module.exports = aa; return module.exports; }

Segunda vía

function require(){ module.exports = {}; var exports = module.exports; exports.a = () => {return ''a'';} exports.b = () => {return ''b'';} return module.exports; }


exports y module.exports son las mismas a menos que reasigne exports dentro de su módulo.

La forma más fácil de pensarlo es pensar que esta línea está implícitamente en la parte superior de cada módulo.

var exports = module.exports = {};

Si, dentro de su módulo, reasigna exports , entonces lo reasigna dentro de su módulo y ya no es igual a module.exports . Por esta razón, si desea exportar una función, debe hacer:

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

Si simplemente asignó su function() { ... } a las exports , estaría reasignando exports para que ya no apunten a module.exports .

Si no quiere referirse a su función por module.exports cada vez, puede hacer:

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

Observe que module.exports es el argumento más a la izquierda.

Adjuntar propiedades a las exports no es lo mismo, ya que no lo está reasignando. Es por eso que esto funciona.

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


var a = {},md={};

// En primer lugar, las exportaciones y module.exports apuntan al mismo objeto vacío

exp = a;//exports =a; md.exp = a;//module.exports = a; exp.attr = "change"; console.log(md.exp);//{attr:"change"}

// Si apunta exp a otro objeto en lugar de apuntar, es propiedad de otro objeto. El md.exp estará vacío Objeto {}

var a ={},md={}; exp =a; md.exp =a; exp = function(){ console.log(''Do nothing...''); }; console.log(md.exp); //{}