module.exports vs export in Node.js


725

Ho trovato il seguente contratto in un modulo Node.js:

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

Mi chiedo qual è la differenza tra module.exportse exportse perché entrambi sono usati qui.





8
Si tratta di riferimenti. Pensa alle esportazioni come a un oggetto variabile locale che punta a module.exports. Se si sovrascrive il valore delle esportazioni, si perde il riferimento a module.exports e module.exports è ciò che si espone come interfaccia pubblica.
Gabriel Llamas,

14
Riepilogo rapido: entrambi exportse module.exportspuntano allo stesso oggetto, a meno che non si riassegni uno. E alla fine module.exportsviene restituito. Quindi, se hai riassegnato exportsa una funzione, non aspettarti una funzione poiché non verrà restituita. Tuttavia, se avessi assegnato una funzione come questa, la exports.func = function...cosa risultante avrebbe la proprietà func con funzione come valore. Perché hai aggiunto la proprietà all'oggetto che exportspuntava ..
Muhammad Umer il

Risposte:


426

L'impostazione module.exportsconsente database_moduledi chiamare la funzione come una funzione quando required. La semplice impostazione exportsnon consentirebbe l'esportazione della funzione poiché il nodo esporta i module.exportsriferimenti agli oggetti . Il seguente codice non consentirebbe all'utente di chiamare la funzione.

module.js

Quanto segue non funzionerà.

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

Quanto segue funzionerà se module.exportsè impostato.

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

consolle

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

In pratica node.js non esporta l'oggetto che exportsattualmente fa riferimento, ma esporta le proprietà di ciò che fa exportsriferimento originariamente. Sebbene Node.js esporti i module.exportsriferimenti agli oggetti , permettendoti di chiamarlo come una funzione.


Secondo motivo meno importante

Hanno impostato entrambi module.exportse exportsper assicurarsi che exportsnon faccia riferimento all'oggetto esportato in precedenza. Impostando entrambi si utilizza exportscome una scorciatoia ed evitare potenziali bug in seguito lungo la strada.

L'uso exports.prop = true invece di module.exports.prop = truesalva i caratteri ed evita confusione.


8
@ajostergaard: capita solo di essere il nome della biblioteca da cui è stato preso l'esempio dell'OP. Nel modulo, consente all'autore di scrivere cose come nano.version = '3.3'invece di module.exports.version = '3.3', che legge un po 'più chiaramente. (Si noti che nanoè una variabile locale, dichiarata un po 'prima che siano impostate le esportazioni del modulo .)
josh3736

3
@lime - grazie - Sono contento che sia in gran parte irrilevante perché se non lo fosse significherebbe che avrei frainteso completamente tutto. : - | :)
ostergaard

Ehi Lime, questa è una risposta piuttosto vecchia ma spero che tu possa chiarire qualcosa. Se dovessi impostare module.exportsma non exports , il mio codice continuerebbe a funzionare? Grazie per qualsiasi aiuto!
Asad Saeeduddin,

1
@Asad Sì, la funzione verrà esportata correttamente se impostatomodule.exports
Lime

@Liam grazie per la preziosa risposta. ancora qualche query - all'ingresso di server.js, quali sono i valori di module.exports ed export? module.exports dovrebbe essere nullo e le esportazioni sono impostate su un oggetto vuoto? È questa eredità o esiste un caso d'uso valido per indirizzare mai export e module.exports a due oggetti diversi?
Sushil,

504

Anche se alla domanda è stata data risposta e accettata molto tempo fa, voglio solo condividere i miei 2 centesimi:

Puoi immaginare che all'inizio del tuo file ci sia qualcosa di simile (solo per spiegazione):

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

inserisci qui la descrizione dell'immagine

Quindi, qualunque cosa tu faccia, tieni presente che module.exportse NON exportsverrà restituito dal tuo modulo quando hai bisogno di quel modulo da qualche altra parte.

Quindi quando fai qualcosa del tipo:

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

Stai aggiungendo 2 funzioni ae ball'oggetto anche su quali module.exportspunti, quindi il typeofrisultato di ritorno sarà un object:{ a: [Function], b: [Function] }

Naturalmente, questo è lo stesso risultato che otterrai se stai usando module.exportsin questo esempio invece di exports.

Questo è il caso in cui vuoi che ti module.exportscomporti come un contenitore di valori esportati. Considerando che, se vuoi solo esportare una funzione di costruzione, c'è qualcosa che dovresti sapere sull'uso di module.exportso exports; (Ricorda ancora che module.exportsverrà restituito quando hai bisogno di qualcosa, non export).

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

Ora il typeofrisultato di ritorno è 'function'e puoi richiederlo e invocare immediatamente come:
var x = require('./file1.js')();perché sovrascrivi il risultato di ritorno in modo che sia una funzione.

Tuttavia, usando exportsnon puoi usare qualcosa come:

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

Perché con exports, il riferimento non punta più all'oggetto in cui module.exportspunta, quindi non c'è più una relazione tra exportse module.exports. In questo caso module.exportspunta ancora all'oggetto vuoto {}che verrà restituito.

Anche la risposta accettata da un altro argomento dovrebbe aiutare: Javascript passa per riferimento?


2
Bella spiegazione ma ancora non capisco come si possa omettere completamente module.exportsda un modulo, ad esempio in questo npmpacchetto: github.com/tj/consolidate.js/blob/master/lib/consolidate.js
CodyBugstein

4
@Imray la spiegazione è qui: JavaScript passa per riferimento? exports.a = function(){}; works, exports = function(){} doesn't work
cirpo,

29
oooo finalmente questa risposta lo spiega. Fondamentalmente l'esportazione si riferisce a un oggetto a cui è possibile aggiungere proprietà ma se lo si riassegna per funzionare, non si associa più una proprietà a quell'oggetto originale. Ora export si riferisce alla funzione mentre module.exports punta ancora a quell'oggetto e poiché è quello che viene restituito. Si può dire che l'esportazione è stata sostanzialmente raccolta di rifiuti.
Muhammad Umer,

5
Allora, che senso ha usare exports? Perché non usare sempre solo module.exportsse si tratta solo di una riassegnazione variabile? Mi sembra confuso.
jedd.ahyoung,

1
@ jedd.ahyoung È meno complicato scrivere exports.somethinginvece dimodule.exports.something
Srle

209

Fondamentalmente la risposta sta in ciò che accade realmente quando un modulo è richiesto tramite requireistruzione. Supponendo che questa sia la prima volta che viene richiesto il modulo.

Per esempio:

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

contenuto di file1.js:

module.exports = '123';

Quando viene eseguita l'istruzione precedente, Moduleviene creato un oggetto. La sua funzione di costruzione è:

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 = [];
}

Come vedi ogni oggetto del modulo ha una proprietà con nome exports. Questo è ciò che alla fine viene restituito come parte di require.

Il prossimo passo da fare è avvolgere il contenuto di file1.js in una funzione anonima come di seguito:

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

E questa funzione anonima viene invocata nel modo seguente, modulequi si riferisce Moduleall'oggetto creato in precedenza.

(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");

Come possiamo vedere all'interno della funzione, si exportsparla di argomento formale module.exports. In sostanza è una comodità fornita al programmatore del modulo.

Tuttavia, questa comodità deve essere esercitata con cura. In ogni caso, se si tenta di assegnare un nuovo oggetto alle esportazioni, assicurarsi di farlo in questo modo.

exports = module.exports = {};

Se lo facciamo nel modo sbagliato , module.exportsrimanderemo comunque all'oggetto creato come parte dell'istanza del modulo.

exports = {};

Di conseguenza, l'aggiunta di qualcosa all'oggetto export precedente non avrà alcun effetto sull'oggetto module.exports e nulla verrà esportato o restituito come parte di request.


8
Mi hai perso quiexports = module.exports = {};
Giant Elk

2
Penso che questa dovrebbe essere la risposta migliore, spiega perché func()fallisce nella risposta di @ William!
tortora il

2
Non vedo alcun vantaggio da aggiungere exports = module.exports = app;all'ultima riga del codice. Sembra che module.exportsverrà esportato e non lo useremo mai exports, perché è di nuovo all'ultima riga del codice. Quindi, perché non aggiungiamo semplicementemodule.exports = app;
lvarayut il

79

Inizialmente, module.exports=exportse la requirefunzione restituisce l'oggetto a cui si module.exportsriferisce.

se aggiungiamo proprietà all'oggetto, diciamo exports.a=1, allora module.exports ed export fanno ancora riferimento allo stesso oggetto. Quindi, se chiamiamo request e assegniamo il modulo a una variabile, allora la variabile ha una proprietà a e il suo valore è 1;

Ma se ne sostituiamo uno, ad esempio, ora exports=function(){}sono diversi : export si riferisce a un nuovo oggetto e module.exports si riferisce all'oggetto originale. E se richiediamo il file, non restituirà il nuovo oggetto, poiché module.exports non si riferisce al nuovo oggetto.

Per me, continuerò ad aggiungere nuove proprietà o a sovrascriverle entrambe su un nuovo oggetto. Basta ignorare uno non è giusto. E tieni presente che module.exportsè il vero capo.


1
Sì, questa è in realtà la vera risposta. È conciso e chiaro. Altri possono avere ragione ma essere pieni di termini fantasiosi e non concentrarsi esattamente sulla risposta a questa domanda.
Khoa

Questa è di gran lunga la risposta più chiara! Nel caso in cui si desidera un segnalibro, questo è il link preciso: stackoverflow.com/questions/7137397/...
lambdarookie

56

exportse module.exportssono uguali a meno che non si riassegni exportsall'interno del modulo.

Il modo più semplice di pensarci è pensare che questa linea sia implicitamente al vertice di ogni modulo.

var exports = module.exports = {};

Se, all'interno del modulo, lo riassegni exports, lo riassegni all'interno del modulo e non è più uguale module.exports. Ecco perché, se si desidera esportare una funzione, è necessario:

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

Se semplicemente assegnato il vostro function() { ... }a exports, si sarebbe riassegnando exportsa nessun punto più a module.exports.

Se non vuoi fare riferimento alla tua funzione module.exportsogni volta, puoi fare:

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

Si noti che module.exportsè l'argomento più a sinistra.

Collegare le proprietà a exportsnon è lo stesso poiché non lo si sta riassegnando. Ecco perché funziona

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

9
Questo è stato il più facile da capire tra tutte le risposte!
Adarsh ​​Konchady,

2
Bello e semplice
fibono

1
Modo semplice e più semplice per comprendere questa funzione.
FilipeCanatto,

27

JavaScript passa gli oggetti tramite la copia di un riferimento

È una sottile differenza a che fare con il modo in cui gli oggetti vengono passati per riferimento in JavaScript.

exportsed module.exportsentrambi puntano allo stesso oggetto. exportsè una variabile ed module.exportsè un attributo dell'oggetto modulo.

Di 'che scrivo qualcosa del genere:

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

exportse module.exportsora indicano oggetti diversi. La modifica delle esportazioni non modifica più module.exports.

Quando viene verificata la funzione di importazione module.exports, viene visualizzata{b:12}


6
La migliore risposta imho!
Mr. AJ,

1
"JavaScript passa per riferimento" - No.
xehpuk

13

Faccio solo un test, si scopre che, all'interno del codice del modulo di nodejs, dovrebbe essere qualcosa del genere:

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

così:

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: ma, mentre in questo 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)

Lyman, quindi module.exportsè una specie di 'affare reale' da cui parte il nodo ma a un certo punto dovrai aggiungere tutto il tuo exportsa module.exportsmeno che tu non stia usando un exports.namespace(caso 2 sopra), che in quel caso sembra essere come nodo gestiva un extends(module.exports, exports);aggiunta di tutte le esigenze degli spazi dei nomi 'di exportsal module.exportsoggetto? In altre parole, se stai usando exports, probabilmente vuoi impostare le proprietà su di esso?
Cody,

11

Ecco una buona descrizione scritta sui moduli del nodo in node.js nel libro di azione della pubblicazione Manning .
Ciò che alla fine viene esportato nella tua applicazione è module.exports.
export
è impostato semplicemente come riferimento globale a module.exports , che inizialmente è definito come un oggetto vuoto a cui è possibile aggiungere proprietà. Quindi exports.myFunc è solo una scorciatoia per module.exports.myFunc .

Di conseguenza, se le esportazioni sono impostate su qualsiasi altra cosa, interrompe il riferimento tra module.exports ed export . Perché module.exportsè ciò che viene realmente esportato, le esportazioni non funzioneranno più come previsto, non fanno più riferimento al modulo .exports . Se si desidera mantenere quel collegamento, è possibile effettuare nuovamente le esportazioni di riferimento module.exports come segue:

module.exports = exports = db;

8

Ho superato alcuni test e penso che questo possa far luce sull'argomento ...

app.js:

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

versioni di /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] }"

Ho anche aggiunto nuovi file:

./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(){};

Otteniamo l'output "@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(){};

Otteniamo l'output "@routes {fn: {}, user: {}}"


./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(){};

Otteniamo l'output "@routes {user: [Function: user]}" Se passiamo user.jsa { ThisLoadedLast: [Function: ThisLoadedLast] }, otteniamo l'output "@routes {ThisLoadedLast: [Function: ThisLoadedLast]}".


Ma se modifichiamo ./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(){};

... otteniamo "@routes {fn: {fn: [Function: fn]}, ThisLoadedLast: {ThisLoadedLast: [Function: ThisLoadedLast]}}"

Quindi suggerirei sempre di usare module.exportsnelle definizioni del tuo modulo.

Non capisco completamente cosa stia succedendo internamente con Node, ma per favore commenta se puoi dare più senso a questo perché sono sicuro che aiuta.

- Buona codifica


Penso che siano inutilmente complicati e confusi. Dovrebbe essere trasparente e intuitivo.
ngungo

Sono d'accordo. Può essere utile per lo spazio dei nomi in alcune circostanze, ma generalmente non creerà o distruggerà nulla.
Cody,

4

Questo mostra come require()funziona nella sua forma più semplice, estratto da Eloquent JavaScript

Problema Non è possibile per un modulo esportare direttamente un valore diverso dall'oggetto export, come una funzione. Ad esempio, un modulo potrebbe voler esportare solo il costruttore del tipo di oggetto che definisce. In questo momento, non può farlo perché request utilizza sempre l' exportsoggetto che crea come valore esportato.

Soluzione Fornire ai moduli un'altra variabile, moduleche è un oggetto con una proprietà exports. Questa proprietà inizialmente punta all'oggetto vuoto creato da request, ma può essere sovrascritta con un altro valore per esportare qualcos'altro.

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);

Ho dovuto ricrearlo in Node e testare alcune cose fino a quando ho capito, faccio schifo. Fondamentalmente, la funzione interna creata per il modulo non restituisce nemmeno l'oggetto di esportazione. Quindi l'oggetto "exports" non viene effettivamente riassegnato nel modulo, ad esempio se si tenta di scrivere export = "questa è ora una stringa" direttamente. L'oggetto esiste solo come riferimento. Questo è un comportamento che non credo di aver capito bene fino ad ora.
danielgormly,

4

Ecco il risultato di

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

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

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

inserisci qui la descrizione dell'immagine

Anche:

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

//YES

Nota: la specifica CommonJS consente solo l'uso della variabile export per esporre i membri pubblici. Pertanto, il modello di esportazione denominato è l'unico realmente compatibile con le specifiche CommonJS. L'uso di module.exports è un'estensione fornita da Node.js per supportare una gamma più ampia di modelli di definizione del modulo.


4
var a = {},md={};

// Innanzitutto, export e module.exports indicano lo stesso oggetto vuoto

exp = a;//exports =a;
md.exp = a;//module.exports = a;

exp.attr = "change";

console.log(md.exp);//{attr:"change"}

// Se punti exp su un altro oggetto invece che su point, è proprietà di un altro oggetto. Md.exp sarà vuoto Object {}

var a ={},md={};
exp =a;
md.exp =a;

exp = function(){ console.log('Do nothing...'); };

console.log(md.exp); //{}

4

Dai documenti

La variabile export è disponibile nell'ambito di un file a livello di modulo e viene assegnato il valore di module.exports prima che il modulo venga valutato.

Permette una scorciatoia, in modo che module.exports.f = ... possa essere scritto in modo più succinto come export.f = .... Tuttavia, tieni presente che come ogni variabile, se un nuovo valore viene assegnato alle esportazioni, è non più associato a module.exports:

È solo una variabile che punta a module.exports.


4

Ho trovato questo link utile per rispondere alla domanda sopra.

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

Per aggiungere agli altri post Il sistema del modulo nel nodo fa

var exports = module.exports 

prima di eseguire il tuo codice. Quindi, quando vuoi export = pippo, probabilmente vuoi fare module.exports = exports = pippo ma usare export.foo = pippo dovrebbe andare bene


git link non funziona
Jesse Hattabaugh,

Il collegamento è ora risolto.
Paweł Gościcki,

3

"Se vuoi che la radice dell'esportazione del tuo modulo sia una funzione (come un costruttore) o se vuoi esportare un oggetto completo in un compito invece di costruirlo una proprietà alla volta, assegnalo a module.exports invece di esportazioni ". - http://nodejs.org/api/modules.html


3

module.exportsed exportsentrambi puntano allo stesso oggetto prima che il modulo venga valutato.

Qualsiasi proprietà aggiunta module.exports all'oggetto sarà disponibile quando il modulo viene utilizzato in un altro modulo mediante l' requireistruzione. exportsè una scorciatoia resa disponibile per la stessa cosa. Per esempio:

module.exports.add = (a, b) => a+b

equivale a scrivere:

exports.add = (a, b) => a+b

Quindi va bene finché non si assegna un nuovo valore alla exportsvariabile. Quando fai qualcosa del genere:

exports = (a, b) => a+b 

quando si assegna un nuovo valore ad exportsesso non ha più riferimento all'oggetto esportato e quindi rimarrà locale al modulo.

Se stai pianificando di assegnare un nuovo valore module.exportspiuttosto che aggiungere nuove proprietà all'oggetto iniziale reso disponibile, probabilmente dovresti considerare di fare come indicato di seguito:

module.exports = exports = (a, b) => a+b

Il sito web Node.js ha un'ottima spiegazione di questo.


2

1.exports -> usa come utility singleton
2. module-export -> usa come oggetti logici come servizio, modello ecc


2

Creiamo un modulo con 2 modi:

Senso unico

var aa = {
    a: () => {return 'a'},
    b: () => {return 'b'}
}

module.exports = aa;

Secondo modo

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

Ed è così che Require () integrerà il modulo.

Primo modo:

function require(){
    module.exports = {};
    var exports = module.exports;

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

    return module.exports;
}

Secondo modo

function require(){
    module.exports = {};
    var exports = module.exports;

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

    return module.exports;
}

2

perché entrambi sono usati qui

Credo che vogliono solo essere chiari su questo module.exports, exportse nanopuntare alla stessa funzione, che consente di utilizzare entrambe le variabili per chiamare la funzione all'interno del file. nanofornisce un contesto a ciò che fa la funzione.

exportsnon verrà esportato (solo module.exports), quindi perché preoccuparsi di sovrascrivere anche quello?

Il compromesso di verbosità limita il rischio di futuri bug, come l'utilizzo exportsanziché module.exportsall'interno del file. Fornisce inoltre chiarimenti che module.exportse exportsdi fatto indicano lo stesso valore.


module.exports vs exports

Finché non si riassegna module.exportso exports(e invece si aggiungono valori all'oggetto a cui si riferiscono entrambi), non si avranno problemi e si può tranquillamente utilizzare exportsper essere più concisi.

Quando si assegnano a un non oggetto, ora indicano punti diversi che possono creare confusione a meno che non si desideri intenzionalmente module.exportsqualcosa di specifico (come una funzione).

L'impostazione exportssu un non oggetto non ha molto senso in quanto dovrai impostare module.exports = exportsalla fine per poterlo utilizzare in altri file.

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

Perché assegnare module.exportsa una funzione?

Più conciso! Confronta quanto è più breve il secondo esempio:

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

app1.js: 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


2

inserisci qui la descrizione dell'immagine

Ogni file che crei è un modulo. il modulo è un oggetto. Ha una proprietà chiamata exports : {}che è un oggetto vuoto per impostazione predefinita.

è possibile creare funzioni / middleware e aggiungere a questo le esportazioni vuoti oggetto, come exports.findById() => { ... } poi requirein qualsiasi punto della app e l'uso ...

controllori / user.js

exports.findById = () => {
    //  do something
}

richiede in route.js di utilizzare:

const {findyId} = './controllers/user'

2

Per comprendere le differenze, devi prima capire cosa fa Node.js per ogni modulo durante il runtime. Node.js crea una funzione wrapper per ogni modulo:

 (function(exports, require, module, __filename, __dirname) {

 })()

Si noti che il primo parametro exportsè un oggetto vuoto e il terzo parametro moduleè un oggetto con molte proprietà e una delle proprietà è denominata exports. Questo è ciò che exportsviene e ciò che module.exportsviene. Il primo è un oggetto variabile e il secondo è una proprietà moduledell'oggetto.

All'interno del modulo, Node.js fa automaticamente questa cosa all'inizio :,module.exports = exports e alla fine ritorna module.exports.

Quindi puoi vedere che se riassegni un valore a exports, non avrà alcun effetto su module.exports. (Semplicemente perché exportspunta a un altro nuovo oggetto, ma module.exportscontiene ancora il vecchio exports)

let exports = {};
const module = {};
module.exports = exports;

exports = { a: 1 }
console.log(module.exports) // {}

Ma se aggiorni le proprietà di exports, avrà sicuramente effetto su module.exports. Perché entrambi indicano lo stesso oggetto.

let exports = {};
const module = {};
module.exports = exports;

exports.a = 1;
module.exports.b = 2;
console.log(module.exports) // { a: 1, b: 2 }

Si noti inoltre che se si riassegna un altro valore a module.exports, allora sembra privo di significato per gli exportsaggiornamenti. Ogni aggiornamento su exportsviene ignorato perché module.exportspunta a un altro oggetto.

let exports = {};
const module = {};
module.exports = exports;

exports.a = 1;
module.exports = {
  hello: () => console.log('hello')
}
console.log(module.exports) // { hello: () => console.log('hello')}

0

nel nodo js module.js viene utilizzato per eseguire il modulo module.load. ogni volta che il nodo esegue un file, avvolge il contenuto del file js come segue

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

a causa di questo wrapping all'interno del tuo codice sorgente js puoi accedere ad esportazioni, richieste, moduli, ecc. questo approccio è usato perché non c'è altro modo per ottenere le funzionalità scritte nel file js su un altro.

quindi il nodo esegue questa funzione incartata usando c ++. in quel momento verranno riempiti gli oggetti esportati passati in questa funzione.

all'interno di questa funzione è possibile vedere i parametri di esportazione e modulo. attualmente l'export è un membro pubblico della funzione di costruzione del modulo.

guarda il seguente codice

copia questo codice in 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 questo codice su 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');}

ora eseguito usando il nodo

questo è l'output

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

export è [oggetto oggetto]

object.keys di foo: name is function () {console.log ('funzione per esportare i moduli')} funzione per esportare i moduli

ora rimuovi la riga commentata in a.js e commenta la riga sopra quella riga e rimuovi l'ultima riga di b.js ed esegui.

nel mondo javascript non è possibile riassegnare l'oggetto passato come parametro ma è possibile modificare il membro pubblico della funzione quando l'oggetto di quella funzione è impostato come parametro su un'altra funzione

ricorda

usa module.exports su e solo se vuoi ottenere una funzione quando usi richiedi parola chiave. nell'esempio sopra abbiamo var foo = require (a.js); puoi vedere che possiamo chiamare foo come una funzione;

questo è il modo in cui la documentazione del nodo lo spiega "L'oggetto export viene creato dal sistema Module. A volte questo non è accettabile, molti vogliono che il loro modulo sia un'istanza di una classe. Per fare ciò assegnare l'oggetto di esportazione desiderato a module.exports."


0
  1. Entrambi module.exportse exportsindicano lo stesso 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"

    È possibile passare balla riga 3 in a, l'uscita è inversa. La conclusione è:

    ae bsono indipendenti.

  2. Quindi module.exports = exports = nano = function database_module(cfg) {...}equivale a:

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

    Si presuppone che quanto sopra module.jssia richiesto da foo.js. I vantaggi di module.exports = exports = nano = function database_module(cfg) {...}sono evidenti ora:

    • In foo.js, poiché module.exportsè require('./module.js'):

      var output = require('./modules.js')();
    • In moduls.js: è possibile utilizzare exportsinvece di module.exports.

Quindi, sarai felice se entrambi exportse module.exportsindicando la stessa cosa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.