Was ist der Zweck von Node.js module.exports und wie verwenden Sie es?

1432

Was ist der Zweck von Node.js module.exports und wie verwenden Sie es?

Ich kann anscheinend keine Informationen dazu finden, aber es scheint ein ziemlich wichtiger Teil von Node.js zu sein, wie ich es oft im Quellcode sehe.

Laut der Node.js-Dokumentation :

Modul

Ein Verweis auf den Strom module. Insbesondere module.exports ist das gleiche wie das Exportobjekt. Siehe src/node.jsfür weitere Informationen.

Das hilft aber nicht wirklich.

Was genau macht module.exportsund was wäre ein einfaches Beispiel?

mrwooster
quelle

Antworten:

1590

module.exportsist das Objekt, das als Ergebnis eines requireAufrufs tatsächlich zurückgegeben wird .

Die exportsVariable wird anfänglich auf dasselbe Objekt gesetzt (dh es handelt sich um eine Kurzform "Alias"), sodass Sie im Modulcode normalerweise Folgendes schreiben würden:

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

zum Exportieren (oder "Belichten") der Funktionen myFunc1mit internem Gültigkeitsbereich und myFunc2.

Und im aufrufenden Code würden Sie verwenden:

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

wobei die letzte Zeile zeigt, wie das Ergebnis von require(normalerweise) nur ein einfaches Objekt ist, auf dessen Eigenschaften zugegriffen werden kann.

NB: Wenn Sie überschreiben exports, wird nicht mehr darauf verwiesen module.exports. Wenn Sie also ein neues Objekt (oder eine Funktionsreferenz) zuweisen möchten, exportssollten Sie auch dieses neue Objekt zuweisenmodule.exports


Es ist erwähnenswert, dass der dem exportsObjekt hinzugefügte Name nicht mit dem internen Gültigkeitsbereich des Moduls für den Wert übereinstimmen muss, den Sie hinzufügen. Sie könnten also Folgendes haben:

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

gefolgt von:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName
Alnitak
quelle
119
Gute Antwort - es scheint mir, dass "Exposes" eine bessere Terminologie gewesen wäre als "Exporte"
UpTheCreek
2
@ApopheniaOverload - Sie können "exports.func1, exports.func2 usw." ausführen, um mehrere exponierte Methoden aus einer Datei zu erhalten.
Hellatan
73
Das Modul require sollte var m = require ('./ mymodule') sein; , mit dem Punkt und dem Schrägstrich. Auf diese Weise weiß Node.js, dass wir ein lokales Modul verwenden.
Gui Premonsa
7
Stellen Sie sicher, dass Sie die Syntax: require ('./ module_name') verwenden, da möglicherweise einige andere node.js-Module mit einem bestimmten Namen vorhanden sind. Statt eines eigenen Moduls wird das mit node.js installierte Modul ausgewählt
Sazid
3
@UpTheCreek Es gibt eine lange Tradition, die öffentlichen Symbole eines Moduls als "exportiert" zu bezeichnen, was auf viele Programmiersysteme und Jahrzehnte zurückgeht. Dies war kein neuer Begriff, der von den Node-Entwicklern erfunden wurde.
Mark Reed
218

Dies wurde bereits beantwortet, aber ich wollte einige Klarstellungen hinzufügen ...

Sie können beides verwenden exportsund module.exportsCode wie folgt in Ihre Anwendung importieren:

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

Der grundlegende Anwendungsfall (z. B. im ExpressJS-Beispielcode) besteht darin, dass Sie Eigenschaften für das exportsObjekt in einer JS-Datei festlegen, die Sie dann mit importierenrequire()

In einem einfachen Zählbeispiel könnten Sie also Folgendes haben:

(counter.js):

var count = 1;

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

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

... dann in Ihrer Anwendung (web.js oder wirklich jede andere .js-Datei):

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

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

In einfachen Worten können Sie sich erforderliche Dateien als Funktionen vorstellen, die ein einzelnes Objekt zurückgeben, und Sie können dem zurückgegebenen Objekt Eigenschaften (Zeichenfolgen, Zahlen, Arrays, Funktionen usw.) hinzufügen, indem Sie sie aktivieren exports.

Manchmal möchten Sie, dass das von einem require()Aufruf zurückgegebene Objekt eine Funktion ist, die Sie aufrufen können, und nicht nur ein Objekt mit Eigenschaften. In diesem Fall müssen Sie auch Folgendes einstellen module.exports:

(sayhello.js):

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

(app.js):

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

Der Unterschied zwischen Exporten und module.exports wird in dieser Antwort hier besser erläutert .

Jed Watson
quelle
Wie kann ich ein Modul aus einem anderen Ordner anfordern, der keinen Stammordner als meinen hat?
Igal
@ user301639 Sie können relative Pfade verwenden, um die Dateisystemhierarchie zu durchlaufen. requireBeginnt relativ zu dem Ordner, node app.jsin dem Sie ausgeführt werden . Ich empfehle, eine neue Frage mit expliziten Beispielen für Code + Ordnerstruktur zu stellen, um eine klarere Antwort zu erhalten.
Jed Watson
1
Ich musste Ihr module.exports-Beispiel optimieren, damit es funktioniert. Datei: var sayHello = require('./ex6_module.js'); console.log(sayHello());und Modul:module.exports = exports = function() { return "Hello World!"; }
Jason Lydon
1
Ich fand das Inkrement-Beispiel wirklich gut und habe es verwendet, um meine Gedanken jedes Mal aufzufrischen, wenn ich mit dem, was ich mit Exporten mache, überlastet werde.
Munkee
module.exports = exports = function(){...}Die zweite exportsist nur eine Variable, oder? Mit anderen Worten, es kann seinmodule.exports = abc = function()
Jeb50
60

Beachten Sie, dass der NodeJS-Modulmechanismus auf CommonJS- Modulen basiert, die in vielen anderen Implementierungen wie RequireJS , aber auch SproutCore , CouchDB , Wakanda , OrientDB , ArangoDB , RingoJS , TeaJS , SilkJS , curl.js oder sogar Adobe Photoshop (über PSLib) unterstützt werden ). Die vollständige Liste der bekannten Implementierungen finden Sie hier .

Sofern Ihr Modul keine knotenspezifischen Funktionen oder Module verwendet, empfehle ich Ihnen dringend, diese zu exportsverwenden, module.exports die nicht Teil des CommonJS-Standards sind und dann meist nicht von anderen Implementierungen unterstützt werden.

Eine weitere NodeJS-spezifische Funktion ist das Zuweisen eines Verweises auf ein neues Objekt, exportsanstatt nur Eigenschaften und Methoden hinzuzufügen, wie im letzten Beispiel von Jed Watson in diesem Thread. Ich persönlich würde diese Praxis als davon abgeraten , diese Pausen die kreisförmige Referenz Unterstützung des Mechanismus Module Commonjs. Es wird dann nicht von allen Implementierungen unterstützt, und das Jed-Beispiel sollte dann so geschrieben werden (oder ähnlich), um ein universelleres Modul bereitzustellen:

(sayhello.js):

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

(app.js):

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

Oder mit ES6-Funktionen

(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!"

PS: Es sieht so aus, als ob Appcelerator auch CommonJS-Module implementiert, jedoch ohne Unterstützung für Zirkelverweise (siehe: Appcelerator- und CommonJS-Module (Caching und Zirkelverweise) ).

Alexandre Morgaut
quelle
35

Einige wenige Dinge, die Sie beachten müssen, wenn Sie einem neuen Objekt einen Verweis zuweisen exportsund / oder modules.exports:

1. Alle Eigenschaften / Methoden, die zuvor an das Original angehängt wurden exportsoder module.exportsnatürlich verloren gehen, weil das exportierte Objekt jetzt auf ein anderes neues Objekt verweist

Dies ist offensichtlich, aber wenn Sie am Anfang eines vorhandenen Moduls eine exportierte Methode hinzufügen, stellen Sie sicher, dass das native exportierte Objekt am Ende nicht auf ein anderes Objekt verweist

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. Falls einer von exportsoder module.exportsauf einen neuen Wert verweist, verweisen sie nicht mehr auf dasselbe Objekt

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. Schwierige Konsequenz. Wenn Sie den Verweis auf beide exportsund ändern module.exports, ist es schwer zu sagen, welche API verfügbar ist (es sieht nach module.exportsGewinnen aus).

// 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() {}; 
Alexandre Morgaut
quelle
29

Mit der Eigenschaft module.exports oder dem Exportobjekt kann ein Modul auswählen, was für die Anwendung freigegeben werden soll

Geben Sie hier die Bildbeschreibung ein

Ich habe ein Video zu module_export hier verfügbar

Anish
quelle
18

Wenn Sie Ihren Programmcode auf mehrere Dateien module.exportsaufteilen, werden Variablen und Funktionen für den Verbraucher eines Moduls veröffentlicht. Der require()Aufruf in Ihrer Quelldatei wird durch den entsprechenden Aufruf module.exportsaus dem Modul ersetzt.

Denken Sie beim Schreiben von Modulen daran

  • Modulladungen werden zwischengespeichert, nur der erste Aufruf wertet JavaScript aus.
  • Es ist möglich, lokale Variablen und Funktionen innerhalb eines Moduls zu verwenden, nicht alles muss exportiert werden.
  • Das module.exportsObjekt ist auch als exportsKurzform verfügbar . Verwenden Sie jedoch immer, wenn Sie eine einzige Funktion zurückgeben module.exports.

Modul exportiert Diagramm

Nach: "Module Teil 2 - Module schreiben" .

pspi
quelle
9

Der Verweis-Link lautet wie folgt:

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

Die Eigenschaften von exportsoder module.exports, wie Funktionen oder Variablen, werden im Freien angezeigt

Es gibt etwas, auf das Sie mehr achten müssen: overrideExportieren Sie nicht .

Warum ?

Da nur die Referenz von module.exports exportiert wird, können Sie die Eigenschaften zu den Exporten hinzufügen. Wenn Sie jedoch die Exporte überschreiben, wird der Referenzlink unterbrochen.

gutes Beispiel :

exports.name = 'william';

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

schlechtes Beispiel :

exports = 'william';

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

Wenn Sie nur eine Funktion oder Variable wie folgt verfügbar machen möchten:

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

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

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

Dieses Modul hat nur eine Funktion verfügbar gemacht, und die Eigenschaft name ist für die Außenseite privat.

Qianjiahao
quelle
6

Es gibt einige Standard- oder vorhandene Module in node.js, wenn Sie node.js wie http, sys usw. herunterladen und installieren .

Da sie bereits in node.js sind, wenn wir diese Module verwenden wollen tun wir im Grunde wie Import - Module , aber warum? weil sie bereits in der node.js vorhanden sind. Beim Importieren werden sie aus node.js übernommen und in Ihr Programm eingefügt. Und sie dann benutzen.

Während Exportieren genau das Gegenteil ist, erstellen Sie das gewünschte Modul, sagen wir das Modul Addition.js, und fügen dieses Modul in die Datei node.js ein. Sie tun dies, indem Sie es exportieren.

Bevor ich hier etwas schreibe, denken Sie daran, module.exports.additionTwo ist dasselbe wie exports.additionTwo

Huh, das ist der Grund, den wir mögen

exports.additionTwo = function(x)
{return x+2;};

Sei vorsichtig mit dem Weg

Nehmen wir an, Sie haben ein Modul add.js erstellt.

exports.additionTwo = function(x){
return x + 2;
};

Wenn Sie dies an Ihrer NODE.JS-Eingabeaufforderung ausführen:

node
var run = require('addition.js');

Dies wird fehlerhaft sagen

Fehler: Modul Addition.js kann nicht gefunden werden

Dies liegt daran, dass der Prozess node.js die Datei addation.js nicht kann, da wir den Pfad nicht erwähnt haben. Wir können also den Pfad mithilfe von NODE_PATH festlegen

set NODE_PATH = path/to/your/additon.js

Nun sollte dies ohne Fehler erfolgreich laufen !!

Eine weitere Sache ist, dass Sie die Datei addation.js auch ausführen können, indem Sie NODE_PATH nicht auf die Eingabeaufforderung von nodejs zurücksetzen:

node
var run = require('./addition.js');

Da wir den Pfad hier angeben, indem wir sagen, dass er sich im aktuellen Verzeichnis befindet, ./sollte dies auch erfolgreich ausgeführt werden.

JumpMan
quelle
1
ist es Export oder Export?
Rudrasiva86
Danke für die Hilfe :)
JumpMan
3

Ein Modul kapselt verwandten Code in eine einzelne Codeeinheit. Beim Erstellen eines Moduls kann dies so interpretiert werden, dass alle zugehörigen Funktionen in eine Datei verschoben werden.

Angenommen, es gibt eine Datei Hello.js, die zwei Funktionen enthält

sayHelloInEnglish = function() {
  return "Hello";
};
sayHelloInSpanish = function() {
  return "Hola";
};

Wir schreiben eine Funktion nur, wenn der Nutzen des Codes mehr als ein Aufruf ist.

Angenommen, wir möchten den Nutzen der Funktion für eine andere Datei erhöhen, z. B. World.js. In diesem Fall wird beim Exportieren einer Datei ein Bild angezeigt, das über module.exports abgerufen werden kann.

Sie können beide Funktionen einfach mit dem unten angegebenen Code exportieren

var anyVariable={
 sayHelloInEnglish = function() {
      return "Hello";
    };
  sayHelloInSpanish = function() {
      return "Hola";
    }; 
}
module.export=anyVariable;

Jetzt müssen Sie nur noch den Dateinamen in World.js eingeben, um diese Funktionen nutzen zu können

var world= require("./hello.js");
Shantanu Madane
quelle
Danke Wenn es dir geholfen hat, akzeptiere bitte meine Antwort :)
Shantanu Madane
1
Ein bisschen spät zum
Partykumpel
@ BenTaliadoros Ich denke auch, dass er zu spät ist und ich denke auch, dass sein anyVariable-Objekt viele Fehler aufweist. Die Zeile über der sayHelloInSpanish-Methode sollte nicht mit einem Semikolon (;) enden, und die Funktion sayHelloInSpanish = ist falsch. Alle Dinge sind mit diesem Objekt falsch. Ich werde seine Antwort bearbeiten
göttlich
1
Bearbeiten ist deaktiviert. Was hat alphadogg in dieser Antwort noch bearbeitet?
göttlicher
Einfach formatieren. Es sei denn, es ist eine verrückte es6-Sache, auf die ich nicht gestoßen bin, und ich bin sicher, dass es nicht so ist, dann ist es überhaupt keine gültige JS
Ben Taliadoros
2

Die Absicht ist:

Die modulare Programmierung ist eine Software-Design-Technik, bei der die Funktionalität eines Programms in unabhängige, austauschbare Module unterteilt wird, sodass jedes Modul alles enthält, was zur Ausführung nur eines Aspekts der gewünschten Funktionalität erforderlich ist.

Wikipedia

Ich stelle mir vor, es wird schwierig, große Programme ohne modularen / wiederverwendbaren Code zu schreiben. In nodejs können wir modulare Programme erstellen, indem module.exportswir definieren, womit wir unser Programm verfügbar machen und komponieren require.

Versuchen Sie dieses Beispiel:

fileLog.js

function log(string) { require('fs').appendFileSync('log.txt',string); }

module.exports = log;

stdoutLog.js

function log(string) { console.log(string); }

module.exports = log;

program.js

const log = require('./stdoutLog.js')

log('hello world!');

ausführen

$ node program.js

Hallo Welt!

Versuchen Sie nun, ./stdoutLog.js gegen ./fileLog.js auszutauschen .

Moriarty
quelle
1

Was ist der Zweck eines Modulsystems?

Es erreicht folgende Dinge:

  1. Verhindert, dass unsere Dateien aufblähen und wirklich groß werden. Dateien mit z. B. 5000 Codezeilen sind normalerweise während der Entwicklung sehr schwer zu verarbeiten.
  2. Erzwingt die Trennung von Bedenken. Durch die Aufteilung unseres Codes in mehrere Dateien können wir für jede Datei geeignete Dateinamen festlegen. Auf diese Weise können wir leicht identifizieren, was jedes Modul tut und wo es zu finden ist (vorausgesetzt, wir haben eine logische Verzeichnisstruktur erstellt, für die Sie immer noch verantwortlich sind).

Das Vorhandensein von Modulen erleichtert das Auffinden bestimmter Codeteile, wodurch unser Code besser gewartet werden kann.

Wie funktioniert es?

NodejS verwendet das CommomJS-Modulsystem, das folgendermaßen funktioniert:

  1. Wenn eine Datei etwas exportieren möchte, muss sie es mithilfe der module.exportSyntax deklarieren
  2. Wenn eine Datei etwas importieren möchte, muss sie es mithilfe der require('file')Syntax deklarieren

Beispiel:

test1.js

const test2 = require('./test2');    // returns the module.exports object of a file

test2.Func1(); // logs func1
test2.Func2(); // logs func2

test2.js

module.exports.Func1 = () => {console.log('func1')};

exports.Func2 = () => {console.log('func2')};

Andere nützliche Dinge zu wissen:

  1. Module werden zwischengespeichert . Wenn Sie dasselbe Modul in 2 verschiedene Dateien laden, muss das Modul nur einmal geladen werden. Beim zweiten require()Aufruf von a auf demselben Modul wird a aus dem Cache gezogen.
  2. Module werden synchron geladen . Dieses Verhalten ist erforderlich, wenn es asynchron war, konnten wir nicht require()sofort auf das abgerufene Objekt zugreifen .
Willem van der Veen
quelle
-3
let test = function() {
    return "Hello world"
};
exports.test = test;
Gtm
quelle
4
Dies ist ein ähnliches Beispiel wie im ersten Ausschnitt in der akzeptierten Antwort ( return "Hello world"macht keinen Unterschied), jedoch ohne Erklärung. Bitte stellen Sie vor der Beantwortung sicher, dass Ihre Antwort dem Thema etwas hinzufügt.
Barbansan