Saya telah menemukan kontrak berikut dalam modul Node.js:
module.exports = exports = nano = function database_module(cfg) {...}
Aku ingin tahu whats berbeda antara module.exports
dan exports
dan mengapa keduanya digunakan di sini.
javascript
node.js
commonjs
Andreas Köberle
sumber
sumber
exports
danmodule.exports
arahkan ke objek yang sama, kecuali jika Anda menetapkan kembali satu. Dan pada akhirnyamodule.exports
dikembalikan. Jadi jika Anda dipindahkanexports
ke suatu fungsi maka jangan berharap fungsi karena itu tidak akan dikembalikan. Namun jika Anda telah menetapkan fungsi seperti iniexports.func = function...
maka hal yang dihasilkan akan memiliki properti func dengan fungsi sebagai nilai. Karena Anda menambahkan properti ke objek yangexports
menunjuk ke ..Jawaban:
Pengaturan
module.exports
memungkinkandatabase_module
fungsi dipanggil seperti fungsi saatrequired
. Pengaturan sederhanaexports
tidak akan memungkinkan fungsi untuk diekspor karena simpul mengekspormodule.exports
referensi objek . Kode berikut tidak akan mengizinkan pengguna untuk memanggil fungsi.module.js
Berikut ini tidak akan berfungsi.
Berikut ini akan berfungsi jika
module.exports
diatur.menghibur
Pada dasarnya node.js tidak mengekspor objek yang
exports
saat ini referensi, tetapi mengekspor properti dari apa yangexports
awalnya referensi. Meskipun Node.js mengekspormodule.exports
referensi objek , memungkinkan Anda untuk memanggilnya seperti fungsi.2 alasan paling tidak penting
Mereka mengatur keduanya
module.exports
danexports
memastikanexports
tidak merujuk objek yang diekspor sebelumnya. Dengan menetapkan kedua yang Anda gunakanexports
sebagai steno dan menghindari bug potensial di kemudian hari.Menggunakan
exports.prop = true
alih-alihmodule.exports.prop = true
menyimpan karakter dan menghindari kebingungan.sumber
nano.version = '3.3'
bukanmodule.exports.version = '3.3'
, yang membaca sedikit lebih jelas. (Perhatikan bahwanano
ini adalah variabel lokal, dideklarasikan sedikit sebelum ekspor modul ditetapkan .)module.exports
tetapi tidakexports
, apakah kode saya masih berfungsi? Terima kasih atas bantuannya!module.exports
Meskipun pertanyaan telah dijawab dan diterima sejak lama, saya hanya ingin membagikan 2 sen saya:
Anda dapat membayangkan bahwa di awal file Anda ada sesuatu seperti (hanya untuk penjelasan):
Jadi, apa pun yang Anda lakukan, ingat saja itu
module.exports
dan TIDAKexports
akan dikembalikan dari modul Anda saat Anda membutuhkan modul itu dari tempat lain.Jadi ketika Anda melakukan sesuatu seperti:
Anda menambahkan 2 fungsi
a
danb
ke objek yangmodule.exports
titiknya juga, sehingga hasiltypeof
yang dikembalikan akan menjadiobject
:{ a: [Function], b: [Function] }
Tentu saja, ini adalah hasil yang sama yang akan Anda dapatkan jika Anda menggunakan
module.exports
dalam contoh ini, bukanexports
.Ini adalah kasus di mana Anda ingin Anda
module.exports
berperilaku seperti wadah nilai yang diekspor. Sedangkan, jika Anda hanya ingin mengekspor fungsi konstruktor maka ada sesuatu yang harus Anda ketahui tentang penggunaanmodule.exports
atauexports
; (Ingat lagi yangmodule.exports
akan dikembalikan saat Anda membutuhkan sesuatu, bukanexport
).Sekarang
typeof
hasil yang dikembalikan adalah'function'
dan Anda dapat meminta dan segera memohon seperti:var x = require('./file1.js')();
karena Anda menimpa hasil yang kembali menjadi suatu fungsi.Namun, menggunakan
exports
Anda tidak dapat menggunakan sesuatu seperti:Karena dengan
exports
, referensi tidak menunjuk lagi ke objek di manamodule.exports
menunjuk, jadi tidak ada hubungan antaraexports
danmodule.exports
lagi. Dalam hal inimodule.exports
masih menunjuk ke objek kosong{}
yang akan dikembalikan.Jawaban yang diterima dari topik lain juga akan membantu: Apakah Javascript lulus dengan referensi?
sumber
module.exports
dari modul, misalnya dalamnpm
paket ini : github.com/tj/consolidate.js/blob/master/lib/consolidate.jsexports.a = function(){}; works, exports = function(){} doesn't work
exports
? Mengapa tidak selalu digunakanmodule.exports
jika itu hanya penugasan kembali variabel? Sepertinya membingungkan saya.exports.something
bukannya rumitmodule.exports.something
Pada dasarnya jawabannya terletak pada apa yang sebenarnya terjadi ketika sebuah modul diperlukan melalui
require
pernyataan. Dengan asumsi ini adalah pertama kali modul diperlukan.Sebagai contoh:
isi file1.js:
Ketika pernyataan di atas dieksekusi, sebuah
Module
objek dibuat. Fungsi konstruktornya adalah:Seperti yang Anda lihat setiap objek modul memiliki properti dengan nama
exports
. Inilah yang akhirnya dikembalikan sebagai bagian darirequire
.Langkah selanjutnya adalah membungkus isi file1.js menjadi fungsi anonim seperti di bawah ini:
Dan fungsi anonim ini dipanggil dengan cara berikut, di
module
sini mengacu padaModule
Obyek yang dibuat sebelumnya.Seperti yang dapat kita lihat di dalam fungsi,
exports
argumen formal merujukmodule.exports
. Intinya itu adalah kenyamanan yang diberikan kepada programmer modul.Namun kenyamanan ini perlu dilakukan dengan hati-hati. Dalam kasus apa pun jika mencoba untuk menetapkan objek baru untuk ekspor memastikan kami melakukannya dengan cara ini.
Jika kita melakukannya dengan cara yang salah ,
module.exports
masih akan menunjuk ke objek yang dibuat sebagai bagian dari instance modul.Akibatnya menambahkan sesuatu ke objek ekspor di atas tidak akan berpengaruh pada objek module.exports dan tidak ada yang akan diekspor atau dikembalikan sebagai bagian dari persyaratan.
sumber
exports = module.exports = {};
func()
gagal dalam jawaban @ William!exports = module.exports = app;
pada baris terakhir dari kode. Sepertinyamodule.exports
akan diekspor dan kami tidak akan pernah menggunakanexports
, karena sekali lagi itu pada baris terakhir dari kode. Jadi, kenapa tidak kita tambahkan sajamodule.exports = app;
Awalnya,,
module.exports=exports
danrequire
fungsi mengembalikan objek yangmodule.exports
dimaksud.jika kita menambahkan properti ke objek, katakanlah
exports.a=1
, maka module.exports dan ekspor masih merujuk ke objek yang sama. Jadi jika kita panggil mengharuskan dan menetapkan modul ke variabel, maka variabel tersebut memiliki properti a dan nilainya 1;Tetapi jika kita menimpa salah satu dari mereka, misalnya,
exports=function(){}
maka mereka berbeda sekarang: ekspor merujuk ke objek dan modul baru. Ekspor merujuk ke objek asli. Dan jika kita memerlukan file, itu tidak akan mengembalikan objek baru, karena module.exports tidak merujuk ke objek baru.Bagi saya, saya akan terus menambahkan properti baru, atau menimpa keduanya ke objek baru. Menimpa satu saja tidak benar. Dan perlu diingat bahwa itu
module.exports
adalah bos yang sebenarnya.sumber
exports
danmodule.exports
sama kecuali Anda menetapkan kembaliexports
dalam modul Anda.Cara termudah untuk memikirkannya, adalah dengan berpikir bahwa baris ini secara implisit ada di bagian atas setiap modul.
Jika, dalam modul Anda, Anda menetapkan kembali
exports
, maka Anda menetapkan kembali dalam modul Anda dan tidak lagi samamodule.exports
. Inilah sebabnya, jika Anda ingin mengekspor suatu fungsi, Anda harus melakukan:Jika Anda hanya menetapkan
function() { ... }
untukexports
Anda, Anda akan ditugaskanexports
untuk tidak lagi menunjuk kemodule.exports
.Jika Anda tidak ingin merujuk ke fungsi Anda
module.exports
setiap saat, Anda dapat melakukan:Perhatikan bahwa
module.exports
itulah argumen paling kiri.Melampirkan properti ke
exports
tidak sama karena Anda tidak menugaskannya kembali. Itu sebabnya ini bekerjasumber
JavaScript melewati objek dengan salinan referensi
Ini perbedaan yang halus untuk dilakukan dengan cara benda dilewatkan dengan referensi dalam JavaScript.
exports
danmodule.exports
keduanya menunjuk ke objek yang sama.exports
adalah variabel danmodule.exports
merupakan atribut dari objek modul.Katakanlah saya menulis sesuatu seperti ini:
exports
danmodule.exports
sekarang arahkan ke objek yang berbeda. Memodifikasi ekspor tidak lagi memodifikasi module.exports.Ketika fungsi impor memeriksa
module.exports
mendapat{b:12}
sumber
Saya hanya membuat beberapa tes, ternyata, di dalam kode modul nodejs, seharusnya ada sesuatu seperti ini:
begitu:
1:
2:
3: tapi, dalam hal ini
sumber
module.exports
ini semacam 'real-deal' yang simpulnya padam, tetapi pada titik tertentu Anda harus menambahkan semuaexports
kemodule.exports
kecuali Anda menggunakanexports.namespace
(kasus 2 di atas), yang dalam kasus itu tampaknya seperti Node menjalankanextends(module.exports, exports);
menambahkan semua 'ruang nama'exports
kemodule.exports
objek? Dengan kata lain, jika Anda menggunakanexports
maka Anda mungkin ingin menetapkan properti di atasnya?Berikut ini adalah deskripsi yang baik yang ditulis tentang modul simpul di node.js dalam buku aksi dari publikasi Manning .
Apa yang akhirnya diekspor dalam aplikasi Anda adalah module.exports.
ekspor diatur hanya sebagai referensi global ke module.exports , yang awalnya didefinisikan sebagai objek kosong yang dapat Anda tambahkan properti. Jadi exports.myFunc hanya singkatan untuk module.exports.myFunc .
Akibatnya, jika ekspor diatur ke hal lain, itu mematahkan referensi antara module.exports dan ekspor . Karena module.exportsadalah apa yang benar-benar diekspor, ekspor tidak lagi berfungsi seperti yang diharapkan — itu tidak merujuk modul .ekspor lagi. Jika Anda ingin mempertahankan tautan itu, Anda dapat membuat ekspor referensi module.exports lagi sebagai berikut:
sumber
Saya telah melalui beberapa tes dan saya pikir ini dapat menjelaskan masalah ini ...
app.js
:versi
/routes/index.js
:Saya bahkan menambahkan file baru:
./routes/index.js
:./routes/not-index.js
:./routes/user.js
:Kami mendapatkan output "@routes {}"
./routes/index.js
:./routes/not-index.js
:./routes/user.js
:Kami mendapatkan output "@routes {fn: {}, pengguna: {}}"
./routes/index.js
:./routes/not-index.js
:./routes/user.js
:Kami mendapatkan output "@routes {user: [Fungsi: user]}" Jika kita mengubah
user.js
ke{ ThisLoadedLast: [Function: ThisLoadedLast] }
, kita mendapatkan output "@routes {ThisLoadedLast: [Fungsi: ThisLoadedLast]}".Tetapi jika kita memodifikasi
./routes/index.js
..../routes/index.js
:./routes/not-index.js
:./routes/user.js
:... kita mendapatkan "@routes {fn: {fn: [Function: fn]}, ThisLoadedLast: {ThisLoadedLast: [Function: ThisLoadedLast]}}"
Jadi saya sarankan selalu gunakan
module.exports
dalam definisi modul Anda.Saya tidak sepenuhnya mengerti apa yang terjadi secara internal dengan Node, tetapi tolong beri komentar jika Anda dapat lebih memahami hal ini karena saya yakin itu membantu.
- Selamat coding
sumber
Ini menunjukkan cara
require()
kerjanya dalam bentuknya yang paling sederhana, disarikan dari Eloquent JavaScriptMasalah Tidak mungkin bagi modul untuk secara langsung mengekspor nilai selain objek ekspor, seperti fungsi. Sebagai contoh, sebuah modul mungkin hanya ingin mengekspor konstruktor dari tipe objek yang didefinisikannya. Saat ini, ia tidak dapat melakukan itu karena mengharuskan selalu menggunakan
exports
objek yang dibuatnya sebagai nilai yang diekspor.Solusi Menyediakan modul dengan variabel lain
module
,, yang merupakan objek yang memiliki propertiexports
. Properti ini pada awalnya menunjuk pada objek kosong yang dibuat dengan membutuhkan tetapi dapat ditimpa dengan nilai lain untuk mengekspor sesuatu yang lain.sumber
Ini adalah hasil dari
Juga:
Catatan: Spesifikasi CommonJS hanya memungkinkan penggunaan variabel ekspor untuk mengekspos anggota publik. Oleh karena itu, pola ekspor bernama adalah satu-satunya yang benar-benar kompatibel dengan spesifikasi CommonJS. Penggunaan module.exports adalah ekstensi yang disediakan oleh Node.js untuk mendukung serangkaian pola definisi modul yang lebih luas.
sumber
// Pertama, ekspor dan module.exports menunjuk Obyek kosong yang sama
// Jika Anda mengarahkan exp ke objek lain alih-alih mengarahkannya ke objek lain. Md.exp akan menjadi Objek kosong {}
sumber
Dari dokumen
Ini hanya variabel yang menunjuk ke module.exports.
sumber
Saya menemukan tautan ini berguna untuk menjawab pertanyaan di atas.
http://timnew.me/blog/2012/04/20/exports-vs-module-exports-in-node-js/
Untuk menambahkan ke posting lain Sistem modul dalam simpul tidak
sebelum menjalankan kode Anda. Jadi ketika Anda ingin mengekspor = foo, Anda mungkin ingin melakukan module.exports = ekspor = foo tetapi menggunakan exports.foo = foo harus baik-baik saja
sumber
"Jika Anda ingin root ekspor modul Anda menjadi fungsi (seperti konstruktor) atau jika Anda ingin mengekspor objek lengkap dalam satu tugas alih-alih membangunnya satu properti pada satu waktu, tetapkan ke module.exports daripada ekspor. " - http://nodejs.org/api/modules.html
sumber
module.exports
danexports
keduanya menunjuk ke objek yang sama sebelum modul dievaluasi.Setiap properti yang Anda tambahkan ke
module.exports
objek akan tersedia ketika modul Anda digunakan dalam modul lain menggunakanrequire
pernyataan.exports
adalah jalan pintas yang tersedia untuk hal yang sama. Contohnya:setara dengan menulis:
Jadi tidak apa-apa asalkan Anda tidak menetapkan nilai baru ke
exports
variabel. Ketika Anda melakukan sesuatu seperti ini:karena Anda menetapkan nilai baru untuk
exports
itu tidak lagi memiliki referensi ke objek yang diekspor dan dengan demikian akan tetap lokal ke modul Anda.Jika Anda berencana untuk menetapkan nilai baru
module.exports
daripada menambahkan properti baru ke objek awal yang tersedia, Anda mungkin harus mempertimbangkan melakukan seperti yang diberikan di bawah ini:Situs web Node.js memiliki penjelasan yang sangat bagus tentang ini.
sumber
1.ekspor -> gunakan sebagai utilitas tunggal
2. modul-ekspor -> gunakan sebagai objek logis seperti layanan, model dll
sumber
Mari kita buat satu modul dengan 2 cara:
Satu arah
Cara kedua
Dan ini adalah bagaimana mengharuskan () akan mengintegrasikan modul.
Cara pertama:
Cara kedua
sumber
Saya percaya mereka hanya ingin menjadi jelas bahwa
module.exports
,,exports
dannano
arahkan ke fungsi yang sama - memungkinkan Anda untuk menggunakan salah satu variabel untuk memanggil fungsi dalam file.nano
menyediakan beberapa konteks untuk fungsi apa yang dilakukan.exports
tidak akan diekspor (hanyamodule.exports
akan), jadi mengapa repot-repot menimpanya juga?Trade-off verbosity membatasi risiko bug di masa depan, seperti menggunakan
exports
alih-alihmodule.exports
dalam file. Ini juga memberikan klarifikasi bahwamodule.exports
danexports
pada kenyataannya menunjuk ke nilai yang sama.module.exports
vs.exports
Selama Anda tidak menetapkan ulang
module.exports
atauexports
(dan malah menambahkan nilai ke objek yang sama-sama mereka maksudkan), Anda tidak akan memiliki masalah apa pun dan dapat menggunakan dengan amanexports
untuk lebih ringkas.Saat menetapkan salah satu ke non-objek, mereka sekarang menunjuk ke berbagai tempat yang dapat membingungkan kecuali Anda sengaja ingin
module.exports
menjadi sesuatu yang spesifik (seperti fungsi).Pengaturan
exports
ke non-objek tidak masuk akal karena Anda harus mengaturmodule.exports = exports
pada akhirnya untuk dapat menggunakannya dalam file lain.Mengapa ditugaskan
module.exports
ke suatu fungsi?Lebih ringkas! Bandingkan seberapa pendek contoh kedua:
helloWorld1.js:module.exports.hello = () => console.log('hello world');
app1.js:
helloWorld2.js:let sayHello = require('./helloWorld1'); sayHello.hello; // hello world
module.exports = () => console.log('hello world');
app2.js:
let sayHello = require('./helloWorld2'); sayHello; // hello world
sumber
Setiap file yang Anda buat adalah modul. modul adalah objek. Ini memiliki properti yang disebut
exports : {}
objek kosong secara default.Anda dapat membuat fungsi / middlewares dan menambah ekspor kosong ini keberatan seperti
exports.findById() => { ... }
iturequire
di mana saja di aplikasi Anda dan penggunaan ...controllers / user.js
mengharuskan dalam route.js untuk menggunakan:
sumber
Untuk memahami perbedaannya, Anda harus terlebih dahulu memahami apa yang dilakukan Node.js untuk setiap modul selama runtime. Node.js membuat fungsi wrapper untuk setiap modul:
Perhatikan param pertama
exports
adalah objek kosong, dan param ketigamodule
adalah objek dengan banyak properti, dan salah satu properti dinamaiexports
. Ini dari manaexports
datangnya dan dari manamodule.exports
datangnya. Yang pertama adalah objek variabel, dan yang terakhir adalah properti darimodule
objek.Di dalam modul, Node.js secara otomatis melakukan hal ini di awal :,
module.exports = exports
dan akhirnya kembalimodule.exports
.Jadi Anda dapat melihat bahwa jika Anda menetapkan kembali beberapa nilai
exports
, itu tidak akan berpengaruh apa punmodule.exports
. (Hanya karenaexports
menunjuk ke objek baru lain, tetapimodule.exports
masih memegang yang lamaexports
)Tetapi jika Anda memperbarui properti
exports
, itu pasti akan berpengaruhmodule.exports
. Karena mereka berdua menunjuk ke objek yang sama.Juga perhatikan bahwa jika Anda menetapkan kembali nilai lain
module.exports
, maka tampaknya tidak ada artinya untukexports
pembaruan. Setiap pembaruan aktifexports
diabaikan karenamodule.exports
menunjuk ke objek lain.sumber
di node js module.js file digunakan untuk menjalankan module.load sistem.sekali kali node mengeksekusi file itu membungkus konten file js Anda sebagai berikut
karena ini membungkus di dalam kode sumber Anda dapat mengakses ekspor, memerlukan, modul, dll. pendekatan ini digunakan karena tidak ada cara lain untuk mendapatkan fungsionalitas menulis di file js ke yang lain.
lalu simpul jalankan fungsi terbungkus ini menggunakan c ++. pada saat itu ekspor objek yang masuk ke fungsi ini akan diisi.
Anda dapat melihat di dalam parameter fungsi ini ekspor dan modul. sebenarnya ekspor adalah anggota publik dari fungsi konstruktor modul.
lihat kode berikut
salin kode ini ke b.js
salin kode ini ke a.js
sekarang jalankan menggunakan node
ini adalah output
ekspor adalah [Objek objek]
object.keys of foo: name is function () {console.log ('function to module ekspor')} berfungsi untuk ekspor modul
sekarang hapus baris yang dikomentari di a.js dan komentari baris di atas baris itu dan hapus baris terakhir dari b.js dan jalankan.
di dunia javascript Anda tidak dapat menetapkan kembali objek yang lulus sebagai parameter tetapi Anda dapat mengubah anggota publik fungsi ketika objek fungsi tersebut ditetapkan sebagai parameter ke fungsi lain
ingat
gunakan module.exports aktif dan hanya jika Anda ingin mendapatkan suatu fungsi saat Anda menggunakan membutuhkan kata kunci. dalam contoh di atas kita var foo = membutuhkan (a.js); Anda dapat melihat kami dapat memanggil foo sebagai fungsi;
ini adalah bagaimana dokumentasi simpul menjelaskannya "Objek ekspor dibuat oleh sistem Module. Kadang-kadang ini tidak dapat diterima, banyak yang ingin modul mereka menjadi turunan dari beberapa kelas. Untuk melakukan ini, tetapkan objek ekspor yang diinginkan ke module.exports."
sumber
Anda dapat mengubah
b
pada baris 3 kea
, outputnya terbalik. Kesimpulannya adalah:Jadi
module.exports = exports = nano = function database_module(cfg) {...}
sama dengan:Diasumsikan di atas adalah
module.js
, yang diperlukan olehfoo.js
. Manfaatmodule.exports = exports = nano = function database_module(cfg) {...}
jelas sekarang:Dalam
foo.js
, karenamodule.exports
adalahrequire('./module.js')
:Di
moduls.js
: Anda dapat menggunakanexports
sebagai gantinyamodule.exports
.Jadi, Anda akan senang jika keduanya
exports
danmodule.exports
menunjuk ke hal yang sama.sumber