Apa tujuan dari module.ex Node.js dan bagaimana Anda menggunakannya?

1432

Apa tujuan dari module.ex Node.js dan bagaimana Anda menggunakannya?

Saya tidak dapat menemukan informasi apa pun tentang ini, tetapi tampaknya ini menjadi bagian yang cukup penting dari Node.js seperti yang sering saya lihat dalam kode sumber.

Menurut dokumentasi Node.js :

modul

Referensi ke arus module. Khususnya module.exports sama dengan objek ekspor. Lihat src/node.jsuntuk informasi lebih lanjut.

Tapi ini tidak terlalu membantu.

Apa yang sebenarnya module.exportsdilakukan, dan apa yang akan menjadi contoh sederhana?

mrwooster
sumber

Jawaban:

1590

module.exportsadalah objek yang sebenarnya dikembalikan sebagai hasil requirepanggilan.

The exportsvariabel awalnya ditetapkan untuk objek yang sama (yaitu itu singkatan "alias"), sehingga dalam kode modul yang Anda lakukan biasanya menulis sesuatu seperti ini:

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

untuk mengekspor (atau "mengekspos") fungsi yang dicakup secara internal myFunc1dan myFunc2.

Dan dalam kode panggilan Anda akan menggunakan:

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

di mana baris terakhir menunjukkan bagaimana hasil dari require(biasanya) hanya objek biasa yang propertinya dapat diakses.

NB: jika Anda menimpa exportsmaka itu tidak akan lagi merujuk module.exports. Jadi jika Anda ingin menetapkan objek baru (atau referensi fungsi) exportsmaka Anda juga harus menetapkan objek baru itumodule.exports


Perlu dicatat bahwa nama yang ditambahkan ke exportsobjek tidak harus sama dengan nama yang dicakup secara internal modul untuk nilai yang Anda tambahkan, sehingga Anda dapat memiliki:

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

diikuti oleh:

const m = require('./mymodule');
m.shortName(); // invokes module.myVeryLongInternalName
Alnitak
sumber
119
Jawaban yang bagus - bagi saya sepertinya 'mengekspos' akan menjadi pilihan terminologi yang lebih baik daripada 'ekspor'
UpTheCreek
2
@ApopheniaOverload - Anda dapat melakukan "exports.func1, exports.func2, dll" untuk memiliki beberapa metode terbuka dari satu file.
hellatan
73
Persyaratan modul harus var m = butuhkan ('./ mymodule'); , dengan titik dan garis miring. Dengan cara ini Node.js tahu kami menggunakan modul lokal.
Gui Premonsa
7
Pastikan untuk menggunakan sintaks: require ('./ module_name') karena, mungkin ada beberapa modul node.js lainnya dengan beberapa nama dan alih-alih memilih modul Anda sendiri, itu akan mengambil salah satu yang diinstal dengan node.js
Sazid
3
@UpTheCreek ada tradisi panjang merujuk pada simbol publik yang diekspos oleh modul sebagai 'diekspor', yang berasal dari banyak sistem pemrograman dan dekade. Ini bukan istilah baru yang ditemukan oleh pengembang Node.
Mark Reed
218

Ini sudah dijawab tetapi saya ingin menambahkan beberapa klarifikasi ...

Anda dapat menggunakan keduanya exportsdan module.exportsuntuk mengimpor kode ke aplikasi Anda seperti ini:

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

Kasus penggunaan dasar yang akan Anda lihat (misalnya dalam kode contoh ExpressJS) adalah bahwa Anda menetapkan properti pada exportsobjek dalam file .js yang kemudian Anda impor menggunakanrequire()

Jadi, dalam contoh penghitungan sederhana, Anda dapat memiliki:

(counter.js):

var count = 1;

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

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

... lalu di aplikasi Anda (web.js, atau benar-benar file .js lainnya):

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

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

Secara sederhana, Anda dapat menganggap file yang diperlukan sebagai fungsi yang mengembalikan satu objek, dan Anda dapat menambahkan properti (string, angka, array, fungsi, apa saja) ke objek yang dikembalikan dengan menyetelnya exports.

Terkadang Anda ingin objek dikembalikan dari require()panggilan menjadi fungsi yang dapat Anda panggil, bukan hanya objek dengan properti. Dalam hal ini Anda juga perlu mengatur module.exports, seperti ini:

(sayhello.js):

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

(app.js):

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

Perbedaan antara ekspor dan module.exports dijelaskan lebih baik dalam jawaban ini di sini .

Jed Watson
sumber
bagaimana saya bisa memanggil memerlukan beberapa modul dari folder lain yang tidak memiliki folder root seperti milik saya?
Igal
@ user301639 Anda dapat menggunakan jalur relatif untuk melintasi hierarki sistem file. requiremulai relatif ke folder yang Anda jalankan node app.jsmasuk. Saya sarankan Anda mengirim pertanyaan baru dengan kode eksplisit + contoh struktur folder untuk mendapatkan jawaban yang lebih jelas.
Jed Watson
1
Saya harus mengubah contoh module.exports Anda untuk membuatnya berfungsi. file: var sayHello = require('./ex6_module.js'); console.log(sayHello());dan modul:module.exports = exports = function() { return "Hello World!"; }
Jason Lydon
1
Menemukan contoh kenaikan benar-benar baik dan saya telah menggunakan ini untuk menyegarkan pikiran saya setiap kali saya kelebihan dengan apa yang saya lakukan dengan ekspor.
munkee
module.exports = exports = function(){...}yang ke-2 exportshanyalah variabel bukan? Dengan kata lain, bisa jadimodule.exports = abc = function()
Jeb50
60

Perhatikan bahwa mekanisme modul NodeJS didasarkan pada modul CommonJS yang didukung dalam banyak implementasi lain seperti RequireJS , tetapi juga SproutCore , CouchDB , Wakanda , OrientDB , ArangoDB , RingoJS , TeaJS , TeaJS , SilkJS , curl.js , atau bahkan Adobe Photoshop (via PSLib ). Anda dapat menemukan daftar lengkap dari implementasi yang dikenal di sini .

Kecuali jika modul Anda menggunakan fitur atau modul khusus node, saya sangat menyarankan Anda untuk menggunakannya exportsdaripada module.exports yang bukan merupakan bagian dari standar CommonJS , dan kemudian sebagian besar tidak didukung oleh implementasi lain.

Fitur spesifik NodeJS lainnya adalah ketika Anda menetapkan referensi ke objek baru exportsdaripada hanya menambahkan properti dan metode seperti dalam contoh terakhir yang diberikan oleh Jed Watson di utas ini. Saya pribadi akan mencegah praktik ini karena ini mematahkan dukungan referensi melingkar dari mekanisme modul CommonJS. Maka tidak didukung oleh semua implementasi dan contoh Jed kemudian harus ditulis dengan cara ini (atau yang serupa) untuk memberikan modul yang lebih universal:

(sayhello.js):

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

(app.js):

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

Atau menggunakan fitur 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!"

PS: Sepertinya Appcelerator juga mengimplementasikan modul CommonJS, tetapi tanpa dukungan referensi melingkar (lihat: modul Appcelerator dan CommonJS (caching dan referensi melingkar) )

Alexandre Morgaut
sumber
35

Beberapa hal yang harus Anda perhatikan jika Anda menetapkan referensi ke objek baru ke exportsdan / atau modules.exports:

1. Semua properti / metode yang sebelumnya dilampirkan ke aslinya exports atau module.exportstentu saja hilang karena objek yang diekspor sekarang akan merujuk yang baru

Yang ini jelas, tapi jika Anda menambahkan metode yang diekspor di awal modul yang ada, pastikan objek yang diekspor asli tidak merujuk objek lain di akhir

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. Dalam kasus salah satu exportsatau module.exportsreferensi nilai baru, mereka tidak merujuk ke objek yang sama lagi

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. Konsekuensi rumit. Jika Anda mengubah referensi untuk keduanya exportsdan module.exports, sulit untuk mengatakan API mana yang terbuka (sepertinya module.exportsmenang)

// 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
sumber
29

properti module.exports atau objek ekspor memungkinkan modul memilih apa yang harus dibagikan dengan aplikasi

masukkan deskripsi gambar di sini

Saya punya video di module_export tersedia di sini

anish
sumber
18

Saat membagi kode program Anda ke beberapa file, module.exportsdigunakan untuk mempublikasikan variabel dan fungsi ke konsumen modul. The require()panggilan dalam file sumber Anda diganti dengan yang sesuaimodule.exports diambil dari modul.

Ingat saat menulis modul

  • Modul dimuat dalam cache, hanya panggilan awal yang mengevaluasi JavaScript.
  • Dimungkinkan untuk menggunakan variabel dan fungsi lokal di dalam sebuah modul, tidak semuanya perlu diekspor.
  • The module.exportsobjek juga tersedia sebagai exportssingkatan. Tetapi ketika mengembalikan satu-satunya fungsi, selalu gunakan module.exports.

diagram ekspor modul

Menurut: "Modul Bagian 2 - Modul Menulis" .

pspi
sumber
9

tautan rujukannya seperti ini:

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

properti exportsatau module.exports, seperti fungsi atau variabel, akan diekspos di luar

ada sesuatu yang harus Anda perhatikan: jangan overrideekspor.

kenapa

karena mengekspor hanya referensi dari module.exports, Anda dapat menambahkan properti ke ekspor, tetapi jika Anda menimpa ekspor, tautan referensi akan rusak.

contoh yang baik :

exports.name = 'william';

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

contoh buruk:

exports = 'william';

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

Jika Anda hanya ingin membuka satu fungsi atau variabel, seperti ini:

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

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

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

modul ini hanya menampilkan satu fungsi dan properti nama bersifat pribadi untuk bagian luar.

qianjiahao
sumber
6

Ada beberapa modul default atau yang ada di node.js ketika Anda mengunduh dan menginstal node.js seperti http, sys dll.

Karena mereka sudah ada di node.js, ketika kita ingin menggunakan modul-modul ini, kita pada dasarnya menyukai modul impor , tetapi mengapa? karena mereka sudah ada di node.js. Mengimpor seperti mengambilnya dari node.js dan memasukkannya ke dalam program Anda. Dan kemudian menggunakannya.

Sedangkan Ekspor adalah kebalikannya, Anda membuat modul yang Anda inginkan, katakanlah modul penambahan.js dan menempatkan modul itu ke node.js, Anda melakukannya dengan mengekspornya.

Sebelum saya menulis apa pun di sini, ingat, module.exports.additionTwo sama dengan exports.additionTwo

Hah, jadi itu alasannya, kami suka

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

Hati-hati dengan jalan

Katakanlah Anda telah membuat modul add.js,

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

Ketika Anda menjalankan ini pada command prompt NODE.JS Anda:

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

Ini akan keliru mengatakan

Kesalahan: Tidak dapat menemukan module tambahan.js

Ini karena proses node.js tidak dapat penambahan.js karena kami tidak menyebutkan path. Jadi, kita dapat mengatur jalur dengan menggunakan NODE_PATH

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

Sekarang, ini harus berjalan dengan sukses tanpa kesalahan !!

Satu hal lagi, Anda juga dapat menjalankan file penambahan.js dengan tidak mengatur NODE_PATH, kembali ke prompt perintah nodejs Anda:

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

Karena kami menyediakan path di sini dengan mengatakan itu di direktori saat ./ini, ini juga harus berjalan dengan sukses.

JumpMan
sumber
1
apakah itu ekspor atau ekspor?
rudrasiva86
Terima kasih atas bantuannya :)
JumpMan
3

Modul merangkum kode terkait ke dalam satu unit kode. Saat membuat modul, ini dapat diartikan sebagai memindahkan semua fungsi terkait ke file.

Misalkan ada file Hello.js yang mencakup dua fungsi

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

Kami menulis fungsi hanya ketika utilitas kode lebih dari satu panggilan.

Misalkan kita ingin meningkatkan utilitas fungsi ke file lain katakanlah World.js, dalam hal ini mengekspor file menjadi gambar yang dapat diperoleh oleh module.exports.

Anda cukup mengekspor kedua fungsi dengan kode yang diberikan di bawah ini

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

Sekarang Anda hanya perlu meminta nama file ke World.js inorder untuk menggunakan fungsi-fungsi itu

var world= require("./hello.js");
Shantanu Madane
sumber
Terima kasih Jika itu telah membantu Anda, tolong terima jawabanku :)
Shantanu Madane
1
Agak terlambat ke pesta kawan :)
Ben Taliadoros
@ BenTaliadoros saya juga berpikir dia terlambat dan saya juga berpikir objek anyVariable-nya memiliki banyak kesalahan. baris di atas metode sayHelloInSpanish tidak boleh diakhiri dengan titik koma (;) dan sayHelloInSpanish = fungsi salah. Semua hal salah dengan objek ini. saya akan mengedit jawabannya
ilahi
1
sunting dinonaktifkan. Apa lagi yang diedit alphadogg dalam jawaban ini ??
ilahi
Hanya memformat. Kecuali itu beberapa hal gila yang belum pernah saya temui, dan saya yakin ini tidak, maka itu sama sekali bukan JS yang valid
Ben Taliadoros
2

Maksudnya adalah:

Pemrograman modular adalah teknik desain perangkat lunak yang menekankan pemisahan fungsi suatu program menjadi modul yang independen dan dapat dipertukarkan, sehingga masing-masing berisi semua yang diperlukan untuk menjalankan hanya satu aspek dari fungsi yang diinginkan.

Wikipedia

Saya membayangkan menjadi sulit untuk menulis program besar tanpa kode modular / dapat digunakan kembali. Dalam nodejs kita dapat membuat program modular menggunakan module.exportsmendefinisikan apa yang kita buat dan buat program kita require.

Coba contoh ini:

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

menjalankan

$ node program.js

Halo Dunia!

Sekarang coba swapping ./stdoutLog.js untuk ./fileLog.js .

Moriarty
sumber
1

Apa tujuan dari sistem modul?

Itu mencapai hal-hal berikut:

  1. Membuat file kami tidak kembung hingga ukuran sangat besar. Memiliki file dengan misalnya 5.000 baris kode di dalamnya biasanya sangat sulit untuk ditangani selama pengembangan.
  2. Memaksakan pemisahan kekhawatiran. Setelah kode kami dipecah menjadi beberapa file memungkinkan kami memiliki nama file yang sesuai untuk setiap file. Dengan cara ini kita dapat dengan mudah mengidentifikasi apa yang dilakukan setiap modul dan di mana menemukannya (dengan asumsi kita membuat struktur direktori logis yang masih menjadi tanggung jawab Anda).

Memiliki modul membuatnya lebih mudah untuk menemukan bagian kode tertentu yang membuat kode kita lebih mudah dikelola.

Bagaimana cara kerjanya?

NodejS menggunakan sistem modul CommomJS yang bekerja dengan cara berikut:

  1. Jika sebuah file ingin mengekspor sesuatu, ia harus mendeklarasikannya menggunakan module.exportsintaks
  2. Jika suatu file ingin mengimpor sesuatu, ia harus mendeklarasikannya menggunakan require('file')sintaks

Contoh:

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

Hal lain yang berguna untuk diketahui:

  1. Modul sedang di-cache . Ketika Anda memuat modul yang sama dalam 2 file yang berbeda, modul hanya perlu dimuat satu kali. Kali kedua a require()dipanggil pada modul yang sama dengan yang ditarik dari cache.
  2. Modul dimuat secara sinkron . Perilaku ini diperlukan, jika asinkron kami tidak dapat mengakses objek yang diambil require()langsung.
Willem van der Veen
sumber
-3
let test = function() {
    return "Hello world"
};
exports.test = test;
GT
sumber
4
Ini adalah contoh yang mirip seperti dalam cuplikan pertama dalam jawaban yang diterima ( return "Hello world"tidak ada bedanya), tetapi tanpa penjelasan apa pun. Pastikan sebelum menjawab bahwa jawaban Anda akan menambahkan sesuatu pada subjek.
barbsan