Ada beberapa pustaka Javascript pihak ketiga yang memiliki beberapa fungsi yang ingin saya gunakan di server Node.js. (Secara khusus saya ingin menggunakan pustaka javascript QuadTree yang saya temukan.) Tetapi pustaka ini hanyalah .js
file langsung dan bukan "pustaka Node.js".
Dengan demikian, pustaka ini tidak mengikuti exports.var_name
sintaks yang diharapkan Node.js untuk modulnya. Sejauh yang saya mengerti itu berarti ketika Anda melakukannya module = require('module_name');
atau module = require('./path/to/file.js');
Anda akan berakhir dengan modul tanpa fungsi yang dapat diakses publik, dll.
Pertanyaan saya kemudian adalah "Bagaimana cara memuat file javascript arbitrer ke Node.js sehingga saya dapat memanfaatkan fungsinya tanpa harus menulis ulang sehingga berfungsi exports
?"
Saya sangat baru di Node.js jadi tolong beri tahu saya jika ada beberapa lubang mencolok dalam pemahaman saya tentang cara kerjanya.
EDIT : Meneliti lebih banyak dan sekarang saya melihat bahwa pola pemuatan modul yang digunakan Node.js sebenarnya adalah bagian dari standar yang dikembangkan baru-baru ini untuk memuat pustaka Javascript yang disebut CommonJS . Ia mengatakan ini tepat di halaman dokumen modul untuk Node.js , tapi saya melewatkannya sampai sekarang.
Mungkin akhirnya jawaban atas pertanyaan saya adalah "tunggu sampai penulis perpustakaan Anda sempat menulis antarmuka CommonJS atau lakukan sendiri."
sumber
Jawaban:
Ada metode yang jauh lebih baik daripada menggunakan
eval
:vm
modul.Misalnya, berikut adalah
execfile
modul saya , yang mengevaluasi skrippath
di salah satucontext
atau konteks global:Dan itu bisa digunakan seperti ini:
Dimana
example.js
mengandung:Keuntungan besar dari metode ini adalah Anda memiliki kendali penuh atas variabel global dalam skrip yang dieksekusi: Anda dapat mengirimkan global kustom (melalui
context
), dan semua global yang dibuat oleh skrip akan ditambahkancontext
. Debugging juga lebih mudah karena kesalahan sintaks dan sejenisnya akan dilaporkan dengan nama file yang benar.sumber
runInNewContext
menggunakan konteks global jikacontext
(sebaliknya disebut sebagaisandbox
, dalam dokumen) tidak ditentukan? (hal ini tidak dijelaskan oleh dokumen yang saya temukan)vm
ditawarkan modul dalam kasus ini?Inilah yang menurut saya adalah jawaban yang 'paling benar' untuk situasi ini.
Katakanlah Anda memiliki file skrip bernama
quadtree.js
.Anda harus membuat kustom
node_module
yang memiliki struktur direktori semacam ini ...Semua yang ada di
./node_modules/quadtree/quadtree-lib/
direktori Anda adalah file dari perpustakaan pihak ketiga Anda.Kemudian
./node_modules/quadtree/index.js
file Anda hanya akan memuat pustaka itu dari sistem file dan melakukan pekerjaan mengekspor dengan benar.Sekarang Anda dapat menggunakan
quadtree
modul Anda seperti modul node lainnya ...Saya suka metode ini karena tidak perlu mengubah kode sumber apa pun dari perpustakaan pihak ketiga Anda - jadi lebih mudah untuk memeliharanya. Yang perlu Anda lakukan saat pemutakhiran adalah melihat kode sumbernya dan memastikan bahwa Anda masih mengekspor objek yang tepat.
sumber
npm link
memasukkannya ke dalam aplikasi Anda. Kemudian ditangani seolah-olah itu adalah paket Node.js asli.Cara paling sederhana adalah:
eval(require('fs').readFileSync('./path/to/file.js', 'utf8'));
Ini berfungsi dengan baik untuk pengujian di shell interaktif.sumber
AFAIK, begitulah modul harus dimuat. Namun, alih-alih menggunakan semua fungsi yang diekspor ke
exports
objek, Anda juga dapat memakainya kethis
(apa yang akan menjadi objek global).Jadi, jika Anda ingin menjaga pustaka lain tetap kompatibel, Anda dapat melakukan ini:
atau, ketika perpustakaan eksternal sudah memiliki namespace sendiri, misalnya
jQuery
(bukan bahwa Anda dapat menggunakan yang dalam lingkungan server-side):Dalam lingkungan non-Node,
this
akan menyelesaikan objek global, sehingga menjadikannya variabel global ... yang sudah ada. Jadi seharusnya tidak merusak apapun.Sunting : James Herdman memiliki artikel bagus tentang node.js untuk pemula, yang juga menyebutkan ini.
sumber
Saya tidak yakin apakah saya akan benar-benar menggunakan ini karena ini adalah solusi yang agak hacky, tetapi salah satu cara mengatasinya adalah dengan membangun importir modul mini kecil seperti ini ...
Di dalam file
./node_modules/vanilla.js
:Kemudian ketika Anda ingin menggunakan fungsionalitas perpustakaan Anda, Anda harus memilih nama mana yang akan diekspor secara manual.
Jadi untuk perpustakaan seperti file
./lib/mylibrary.js
...Saat Anda ingin menggunakan fungsinya di kode Node.js ...
Tidak tahu seberapa baik ini semua akan berhasil dalam praktiknya.
sumber
Saya dapat membuatnya berfungsi dengan memperbarui skrip mereka, dengan sangat mudah, hanya menambahkan
module.exports =
jika sesuai ...Misalnya, saya mengambil file mereka dan saya menyalin ke './libs/apprise.js'. Lalu di mana itu dimulai
Saya menetapkan fungsi sebagai
module.exports =
berikut:Jadi saya dapat mengimpor pustaka ke dalam kode saya seperti ini:
Dan saya baik untuk pergi. YMMV, ini dengan webpack .
sumber
include(filename)
Fungsi sederhana dengan pesan kesalahan yang lebih baik (tumpukan, nama file, dll.) Untukeval
, jika terjadi kesalahan:Tetapi bahkan menjadi lebih kotor dengan nodejs: Anda perlu menentukan ini:
Jika tidak, Anda tidak dapat menggunakan variabel global dalam file yang disertakan dengan
include(...)
.sumber