Bagaimana saya dapat berbagi kode antara Node.js dan browser?
Saya membuat sebuah aplikasi kecil dengan klien JavaScript (run di browser) dan Node.js server berkomunikasi menggunakan WebSocket.
Saya ingin berbagi kode antara klien dan server. Aku baru saja mulai dengan Node.js dan pengetahuan saya tentang JavaScript modern adalah sedikit berkarat, untuk sedikitnya. Jadi saya masih mendapatkan kepala saya sekitar CommonJS require() fungsi. Jika saya membuat saya paket dengan menggunakan 'ekspor' objek, maka saya tidak bisa melihat bagaimana saya bisa menggunakan file JavaScript di browser.
Saya ingin membuat satu set metode dan kelas yang digunakan pada kedua ujungnya untuk memudahkan encoding dan decoding pesan, dan lain dicerminkan tugas. Namun, Node.js/CommonJS sistem kemasan tampaknya menghalangi saya dari membuat file JavaScript yang dapat digunakan pada kedua belah pihak.
Saya juga mencoba menggunakan JS.Class untuk mendapatkan lebih ketat OO model, tapi saya menyerah karena saya tidak't tahu bagaimana untuk mendapatkan yang disediakan file JavaScript untuk bekerja dengan require(). Apakah ada sesuatu yang saya hilang di sini?
Jika anda ingin menulis sebuah modul yang dapat digunakan baik di sisi client dan sisi server, saya memiliki sebuah posting blog singkat pada metode cepat dan mudah: Tulisan untuk Node.js dan browser, pada dasarnya sebagai berikut (di mana
ini
adalah sama denganjendela
):Atau ada beberapa proyek-proyek yang bertujuan untuk melaksanakan Node.js API pada sisi klien, seperti Marak's gemini.
Anda juga mungkin tertarik dalam DNode, yang memungkinkan anda untuk mengekspos fungsi JavaScript sehingga dapat dipanggil dari mesin lain menggunakan JSON berbasis protokol jaringan.
Epeli memiliki solusi yang bagus di sini http://epeli.github.com/piler/ yang bahkan bekerja tanpa perpustakaan, hanya menempatkan ini dalam sebuah file yang bernama share.js
Pada sisi server hanya menggunakan:
Dan pada sisi klien hanya memuat file js dan kemudian menggunakan
Pelajari source code jQuery yang membuat ini bekerja di Node.js modul pola, AMD modul pola, dan global di browser:
Saya akan merekomendasikan melihat ke RequireJS adaptor untuk Node.js. Masalahnya adalah bahwa CommonJS modul pola Node.js menggunakan secara default isn't asynchronous, yang menghambat loading di browser web. RequireJS menggunakan AMD pola, yang kedua asynchronous dan kompatibel dengan kedua server dan klien, asalkan anda menggunakan
r.js
adapter.Don't lupa bahwa representasi string dari suatu fungsi JavaScript merupakan source code untuk fungsi itu. Anda hanya bisa menulis fungsi dan konstruktor di dikemas dengan cara sehingga mereka dapat toString()'a dan dikirim ke klien.
Cara lain untuk melakukan ini adalah menggunakan sistem membangun, menempatkan umum kode di file terpisah, dan kemudian memasukkan mereka ke dalam server dan client scripts. I'm menggunakan pendekatan yang sederhana client/server game melalui WebSockets di mana server dan klien keduanya berjalan pada dasarnya sama permainan lingkaran dan klien tersinkronisasi dengan server setiap tick untuk memastikan tidak ada's kecurangan.
Saya membangun sistem untuk permainan ini adalah sederhana Bash script yang menjalankan file melalui C preprocessor dan kemudian melalui sed untuk membersihkan beberapa sampah cpp daun di belakang, jadi aku bisa menggunakan semua normal preprocessor hal-hal seperti #seperti, #define, #ifdef, dll.
Mungkin hal ini tidak sepenuhnya sejalan dengan pertanyaan, tapi saya pikir saya'd berbagi ini.
Saya ingin membuat beberapa string sederhana fungsi utilitas, menyatakan pada String.prototipe, yang tersedia untuk kedua node dan browser. Saya hanya menjaga fungsi-fungsi tersebut dalam sebuah file yang bernama utilities.js (di subfolder) dan dapat dengan mudah referensi baik dari naskah-tag di browser saya kode, dan dengan menggunakan require (menghilangkan .js extension) di saya Node.js script:
my_node_script.js
my_browser_code.html
Saya berharap ini adalah informasi yang berguna untuk orang lain selain saya.
Jika anda menggunakan menggunakan modul bundlers seperti webpack untuk bundel file JavaScript untuk penggunaan di browser, anda hanya dapat menggunakan kembali Node.js modul untuk frontend berjalan di browser. Dengan kata lain, anda Node.js modul dapat dibagi antara Node.js dan browser.
Misalnya, anda memiliki kode berikut sum.js:
Normal Node.js modul: sum.js
Menggunakan modul Node.js
Reuse itu di frontend
Server hanya dapat mengirim JavaScript file sumber ke client (browser) tapi trik ini adalah bahwa klien akan memiliki untuk menyediakan mini "ekspor" lingkungan sebelum dapat
exec
kode dan menyimpannya sebagai modul.Cara sederhana untuk membuat lingkungan seperti itu adalah dengan menggunakan penutupan. Misalnya, katakanlah anda server menyediakan sumber file melalui HTTP suka
http://example.com/js/foo.js
. Browser dapat memuat file yang dibutuhkan melalui XMLHttpRequest dan memuat kode seperti:Kuncinya adalah bahwa klien dapat membungkus kode asing ke dalam fungsi anonim yang akan segera berjalan (penutupan) yang menciptakan "ekspor" objek dan kembali agar anda dapat menetapkan mana anda'd suka, daripada mencemari global namespace. Dalam contoh ini, itu ditugaskan ke jendela atribut
fooModule
yang akan berisi kode yang diekspor oleh filefoo.js
.Tak satu pun dari solusi sebelumnya membawa CommonJS sistem modul untuk browser.
Seperti yang disebutkan dalam jawaban yang lain, ada manajer aset/packager solusi seperti Browserify atau Piler dan ada RPC solusi seperti dnode atau nowjs.
Tapi aku tak't menemukan sebuah implementasi dari CommonJS untuk browser (termasuk
require()
fungsi danekspor
/modul.ekspor
benda-benda, dll.). Jadi saya menulis saya sendiri, hanya untuk menemukan kemudian bahwa orang lain telah menulis lebih baik daripada yang saya punya: https://github.com/weepy/brequire. It's disebut Menuntut (pendek untuk Browser yang memerlukan).Dilihat dari popularitas, manajer aset sesuai dengan kebutuhan sebagian besar pengembang. Namun, jika anda membutuhkan browser pelaksanaan CommonJS, Menuntut mungkin akan sesuai dengan tagihan.
2015 Update: saya tidak lagi menggunakan Menuntut (ini masih't telah diperbarui dalam beberapa tahun). Jika saya'm hanya tulisan kecil, open-source modul dan aku ingin orang untuk dapat dengan mudah menggunakan, maka saya'll mengikuti pola yang mirip dengan Caolan's jawaban (atas) - saya menulis blog post tentang hal itu beberapa tahun yang lalu.
Namun, jika saya'm penulisan modul untuk penggunaan pribadi atau untuk sebuah komunitas yang standar pada CommonJS (seperti Ampersand komunitas) maka saya'll hanya menulis mereka di CommonJS format dan menggunakan Browserify.
now.js juga layak lihat. Hal ini memungkinkan anda untuk memanggil server-side dari client-side dan client-side fungsi dari server-side
Menulis kode seperti RequireJS modul dan tes anda sebagai Melati tes.
Dengan cara ini kode yang dapat dimuat di mana-mana dengan RequireJS dan tes yang akan dijalankan di browser dengan jasmine-html dan dengan jasmine-node Node.js tanpa perlu mengubah kode atau tes.
Berikut adalah contoh kerja]4 selama ini.
Jika anda ingin menulis browser anda di Node.js-seperti gaya yang dapat anda coba dualify.
Tidak ada browser kompilasi kode, sehingga anda dapat menulis aplikasi anda tanpa keterbatasan.
Use case: berbagi aplikasi konfigurasi antara Node.js dan browser (ini hanya sebuah ilustrasi, mungkin bukan pendekatan yang terbaik tergantung pada aplikasi anda).
Masalah: anda tidak dapat menggunakan
jendela
(tidak ada di Node.js) atauglobal
(tidak ada di browser).Solusi:
var config = { foo: 'bar' }; if (typeof modul === 'objek') modul.ekspor = config;
Sekarang anda dapat membuka dev tools dan mengakses variabel global
config
const config = require('./config'); konsol.log(config.foo); // Cetak 'bar'
impor config dari './config'; konsol.log(config.foo); // Cetak 'bar'
Saya menulis modul sederhana, yang dapat diimpor (baik menggunakan butuhkan dalam Node, atau tag script di browser), yang dapat anda gunakan untuk memuat modul-modul kedua dari klien dan dari server.
Contoh penggunaan
1. Mendefinisikan modul
Tempat berikut di file
log2.js
, di dalam web statis file folder:Sederhana seperti itu!
2. Menggunakan modul
Karena itu adalah bilateral modul loader, kita dapat memuat dari kedua belah pihak (client dan server). Oleh karena itu, anda dapat melakukan beberapa hal berikut, tapi anda don't perlu untuk melakukan keduanya sekaligus (apalagi dalam urutan tertentu):
Di Node, it's sederhana:
Ini harus kembali
2
.Jika file anda isn't di Nodus's direktori saat ini, pastikan untuk memanggil
loader.setRoot
dengan path ke web statis file folder (atau di mana pun anda modul).Pertama, menentukan halaman web:
Pastikan anda don't buka file langsung di browser anda, karena menggunakan AJAX, saya sarankan anda melihat pada Python 3's
http.server
modul (atau apa pun yang anda supercepat, baris perintah, folder web server deployment solution) sebagai gantinya.Jika semuanya berjalan dengan baik, ini akan muncul:
Saya menulis ini, itu adalah sederhana untuk menggunakan jika anda ingin mengatur semua variabel ke lingkup global: