Saya ingin meminta file saya selalu oleh root dari proyek saya dan tidak relatif terhadap modul saat ini.
Misalnya jika Anda melihat https://github.com/visionmedia/express/blob/2820f2227de0229c5d7f28009aa432f9f3a7b5f9/examples/downloads/app.js baris 6 Anda akan melihat
express = require('../../')
Itu IMO yang sangat buruk. Bayangkan saya ingin menempatkan semua contoh saya lebih dekat ke root hanya dengan satu level. Itu tidak mungkin, karena saya harus memperbarui lebih dari 30 contoh dan berkali-kali dalam setiap contoh. Untuk ini:
express = require('../')
Solusi saya adalah memiliki case khusus untuk root: jika sebuah string dimulai dengan $ maka itu relatif terhadap folder root proyek.
Bantuan apa pun dihargai, terima kasih
Perbarui 2
Sekarang saya menggunakan require.js yang memungkinkan Anda menulis dengan satu cara dan berfungsi baik pada klien maupun di server. Require.js juga memungkinkan Anda membuat jalur khusus.
Perbarui 3
Sekarang saya pindah ke webpack + tegukan dan saya menggunakan ditingkatkan-perlu untuk menangani modul di sisi server. Lihat di sini alasannya: http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/
Jawaban:
Dan bagaimana dengan:
Ini membutuhkan file seolah-olah itu diperlukan dari file js utama, jadi itu berfungsi dengan baik selama file js utama Anda adalah di root proyek Anda ... dan itu adalah sesuatu yang saya hargai.
sumber
Ada bagian yang sangat menarik di Browserify Handbook :
sumber
node_modules
folder adalah membuatnya lebih sulit untuk nuke (rm -rf node_modules
) foldergit clean
sintaksnya, Anda dapat selalurm -rf node_modules && git checkout node_modules
- pastikan untukgit stash
berjaga-jaga jika ada perubahan padanode_modules
subdirektori.Saya suka membuat
node_modules
folder baru untuk kode bersama, lalu biarkan simpul dan perlu melakukan yang terbaik.sebagai contoh:
Misalnya, jika Anda berada di dalam,
car/index.js
Anda dapatrequire('helper')
dan simpul akan menemukannya!Cara Kerja node_modules
Node memiliki algoritma pintar untuk menyelesaikan modul yang unik di antara platform saingan.
Jika Anda
require('./foo.js')
dari/beep/boop/bar.js
, simpul akan mencari./foo.js
di/beep/boop/foo.js
. Jalur yang dimulai dengan./
atau../
selalu lokal ke file yang memanggilrequire()
.Namun jika Anda memerlukan nama non-relatif seperti
require('xyz')
dari/beep/boop/foo.js
, node mencari jalur ini secara berurutan, berhenti pada pertandingan pertama dan meningkatkan kesalahan jika tidak ada yang ditemukan:Untuk setiap
xyz
direktori yang ada, node pertama-tama akan mencari untukxyz/package.json
melihat apakah"main"
ada lapangan. The"main"
mendefinisikan bidang yang file harus bertanggung jawab jika Andarequire()
jalur direktori.Misalnya, apakah
/beep/node_modules/xyz
ini pertandingan pertama dan/beep/node_modules/xyz/package.json
memiliki:maka ekspor dari
/beep/node_modules/xyz/lib/abc.js
akan dikembalikan olehrequire('xyz')
.Jika tidak ada
package.json
atau tidak ada"main"
bidang,index.js
diasumsikan:sumber
Gambar besar
Tampaknya "sangat buruk" tetapi berikan waktu. Ini sebenarnya sangat bagus.
require()
S eksplisit memberikan transparansi total dan kemudahan pemahaman yang seperti menghirup udara segar selama siklus hidup proyek.Pikirkan seperti ini: Anda membaca contoh, mencelupkan jari kaki Anda ke Node.js dan Anda telah memutuskan itu adalah "IMO benar-benar buruk." Anda adalah pemimpin menebak-nebak dari komunitas Node.js, orang-orang yang telah log jam lebih banyak menulis dan memelihara aplikasi Node.js daripada siapa pun. Apa kesempatan penulis membuat kesalahan pemula? (Dan saya setuju, dari latar belakang Ruby dan Python saya, sepertinya pada awalnya seperti bencana.)
Ada banyak hype dan counter-hype seputar Node.js. Tetapi ketika debu mengendap, kami akan mengakui bahwa modul eksplisit dan paket "lokal pertama" adalah pendorong utama adopsi.
Kasus umum
Tentu saja,
node_modules
dari direktori saat ini, maka orang tua, kemudian kakek nenek, kakek buyut, dll dicari. Jadi paket yang Anda instal sudah berfungsi seperti ini. Biasanya Anda dapatrequire("express")
dari mana saja di proyek Anda dan itu berfungsi dengan baik.Jika Anda menemukan diri Anda memuat file-file umum dari root proyek Anda (mungkin karena mereka adalah fungsi utilitas umum), maka itu adalah petunjuk besar bahwa inilah saatnya untuk membuat paket. Paket sangat sederhana: pindahkan file Anda ke dalam
node_modules/
dan letakkan dipackage.json
sana. Voila! Segala sesuatu di namespace itu dapat diakses dari seluruh proyek Anda. Paket adalah cara yang benar untuk memasukkan kode Anda ke ruang nama global.Penanganan lainnya
Saya pribadi tidak menggunakan teknik ini, tetapi mereka menjawab pertanyaan Anda, dan tentu saja Anda tahu situasi Anda sendiri lebih baik daripada saya.
Anda dapat mengatur
$NODE_PATH
ke root proyek Anda. Direktori itu akan dicari ketika Andarequire()
.Selanjutnya, Anda dapat berkompromi dan membutuhkan file lokal umum dari semua contoh Anda. File umum itu hanya mengekspor ulang file sebenarnya di direktori kakek-nenek.
contoh / unduhan / app.js (dan banyak lainnya menyukainya)
contoh / unduhan / express.js
Sekarang ketika Anda memindahkan file-file itu, kasus terburuk adalah memperbaiki modul satu shim .
sumber
Lihatlah node-rfr .
Sesederhana ini:
sumber
Jika Anda menggunakan benang alih-alih npm, Anda dapat menggunakan ruang kerja .
Katakanlah saya memiliki folder yang
services
ingin saya minta dengan lebih mudah:Untuk membuat ruang kerja Benang, buat
package.json
file di dalamservices folder
:Di package.json utama Anda, tambahkan:
Jalankan
yarn install
dari akar proyek.Lalu, di mana pun dalam kode Anda, Anda dapat melakukan:
bukannya sesuatu seperti:
sumber
IMHO, cara termudah adalah mendefinisikan fungsi Anda sendiri sebagai bagian dari
GLOBAL
objek. BuatprojRequire.js
di root proyek Anda dengan konten berikut:Di file utama Anda sebelum
require
memasukkan modul spesifik proyek:Setelah itu bekerja untuk saya:
@ Totty, saya sudah membuat solusi lain, yang bisa berfungsi jika Anda dijelaskan dalam komentar. Deskripsi akan jadi
tl;dr
, jadi saya lebih baik menampilkan gambar dengan struktur proyek pengujian saya .sumber
prj/some
dariprj/other
(baru saja diujirequire('prj/some'
). Modul umum semua aplikasi Anda dapat pergi ke sana (misalnya lapisan basis data). Tidak akan ada bedanya di mana Anda, katakanlah,lib
berada. Coba dan lihat apakah itu cocok.Saya menggunakan
process.cwd()
dalam proyek saya. Sebagai contoh:Mungkin perlu dicatat bahwa ini akan menghasilkan
require
jalan absolut, meskipun saya belum mengalami masalah dengan ini.sumber
Ada diskusi yang bagus tentang masalah ini di sini .
Saya mengalami masalah arsitektur yang sama: ingin cara memberikan aplikasi saya lebih banyak organisasi dan ruang nama internal, tanpa:
Pada akhirnya, saya memutuskan untuk mengatur kode saya menggunakan konvensi penamaan file daripada direktori. Suatu struktur akan terlihat seperti:
Kemudian dalam kode:
atau hanya
dan dependensi eksternal tersedia dari node_modules seperti biasa:
Dengan cara ini, semua kode aplikasi diatur secara hierarkis ke dalam modul dan tersedia untuk semua kode lain relatif terhadap root aplikasi.
Kerugian utama tentu saja dalam browser file, Anda tidak dapat memperluas / menciutkan pohon seolah-olah itu sebenarnya diatur ke dalam direktori. Tapi saya suka itu sangat eksplisit tentang dari mana semua kode berasal, dan tidak menggunakan 'sihir'.
sumber
../x/x
yang sudah dapat dibaca.Dengan asumsi root proyek Anda adalah direktori kerja saat ini, ini harus bekerja:
sumber
config = require('./config.js');
juga valid.Saya telah mencoba banyak solusi ini. Saya akhirnya menambahkan ini ke bagian atas file utama saya (mis. Index.js):
Ini menambahkan root proyek ke NODE_PATH ketika skrip dimuat. Itu memungkinkan saya untuk meminta file apa pun dalam proyek saya dengan mereferensikan jalur relatifnya dari root proyek seperti
var User = require('models/user')
. Solusi ini akan berfungsi selama Anda menjalankan skrip utama di root proyek sebelum menjalankan apa pun di proyek Anda.sumber
Beberapa jawaban mengatakan bahwa cara terbaik adalah menambahkan kode ke node_module sebagai paket, saya setuju dan mungkin cara terbaik untuk menghilangkan
../../../
memerlukan tetapi tidak satupun dari mereka yang benar-benar memberikan cara untuk melakukannya.dari versi
2.0.0
Anda dapat menginstal paket dari file lokal, yang berarti Anda dapat membuat folder di root Anda dengan semua paket yang Anda inginkan,jadi di package.json Anda dapat menambahkan
modules
(ataufoo
danbar
) sebagai paket tanpa menerbitkan atau menggunakan server eksternal seperti ini:Setelah itu Anda lakukan
npm install
, dan Anda dapat mengakses kodevar foo = require("foo")
, sama seperti yang Anda lakukan dengan semua paket lainnya.info lebih lanjut dapat ditemukan di sini:
https://docs.npmjs.com/files/package.json#local-paths
dan di sini cara membuat paket:
https://docs.npmjs.com/getting-started/creating-node-modules
sumber
Anda dapat menggunakan modul yang saya buat, Undot . Tidak ada yang maju, hanya pembantu sehingga Anda dapat menghindari titik-titik itu dengan mudah.
Contoh:
sumber
Anda dapat mendefinisikan sesuatu seperti ini di app.js Anda:
dan kemudian kapan pun Anda ingin memerlukan sesuatu dari root, di mana pun Anda berada, Anda cukup menggunakan requireFromRoot sebagai ganti vanilla. Sejauh ini berfungsi dengan baik untuk saya.
sumber
requireFromRoot = ((root) => (resource) => require(`${root}/${resource}`))(__dirname);
. Suka solusinya, tetapi apakah Anda benar-benar harus mengikat __dirname seperti itu?require
menjalankan fungsi ini?Inilah cara aktual yang saya lakukan selama lebih dari 6 bulan. Saya menggunakan folder bernama node_modules sebagai folder root saya di proyek, dengan cara ini akan selalu mencari folder itu dari mana-mana saya sebut mutlak membutuhkan:
Ini lebih berguna ketika Anda bersarang ke dalam folder dan itu jauh lebih sulit untuk mengubah lokasi file jika diatur secara absolut. Saya hanya menggunakan 2 persyaratan relatif di seluruh aplikasi saya .
sumber
node_modules
di/src
, dan meninggalkan/node_modules
bagi vendor untuk menjaga hal-hal yang terpisah. Jadi saya punya/src/node_modules
untuk kode lokal dan/node_modules
untuk vendor.NODE_PATH
variabel lingkunganSaya cara termudah untuk mencapai ini adalah dengan membuat tautan simbolis pada startup aplikasi di
node_modules/app
(atau apa pun namanya) yang menunjuk ke sana../app
. Maka Anda bisa meneleponrequire("app/my/module")
. Tautan simbolik tersedia di semua platform utama.Namun, Anda tetap harus membagi barang-barang Anda menjadi modul-modul yang lebih kecil dan dapat dipelihara yang dipasang melalui npm. Anda juga dapat menginstal modul pribadi Anda melalui git-url, jadi tidak ada alasan untuk memilikinya, direktori aplikasi monolitik.
sumber
Dalam proyek Anda sendiri, Anda bisa memodifikasi file .js yang digunakan di direktori root dan menambahkan path-nya ke properti
process.env
variabel. Sebagai contoh:Setelah itu, Anda dapat mengakses properti di mana saja:
sumber
Jawaban lain:
Bayangkan struktur folder ini:
tes
Kemudian di test.js , Anda perlu meminta file seperti ini:
dan di main.js :
Sekarang Anda dapat menggunakan babel dan babel-plugin-module-resolver dengan ini. file babelrc untuk mengkonfigurasi 2 folder root:
Sekarang Anda dapat meminta file dengan cara yang sama dalam tes dan di src :
dan jika Anda ingin menggunakan sintaks modul es6 :
maka Anda mengimpor file dalam tes dan src seperti ini:
sumber
Baru saja menemukan artikel ini yang menyebutkan jalur aplikasi-modul . Ini memungkinkan Anda untuk mengkonfigurasi basis seperti ini:
sumber
Tidak dapat
examples
direktori berisinode_modules
dengan tautan simbolis ke root proyekproject -> ../../
sehingga memungkinkan contoh untuk digunakanrequire('project')
, meskipun ini tidak menghapus pemetaan, itu memungkinkan sumber untuk menggunakanrequire('project')
daripadarequire('../../')
.Saya telah menguji ini, dan itu berhasil dengan v0.6.18.
Daftar
project
direktori:Isi
index.js
memberikan nilai ke propertiexports
objek dan memanggilconsole.log
dengan pesan yang menyatakan itu diperlukan. Isitest.js
isrequire('project')
.sumber
require('project.a')
? Saya pikir itu mungkin berartirequire('project/a')
, meskipunrequire('project').a
juga mungkin?node_modules
direktori di induk terdekat dari kedua file dan tautan kemudian akan sama untuk keduanya. Lihat nodejs.org/api/…project/node_modules/project -> ../
.Jika ada yang mencari cara lain untuk mengatasi masalah ini, inilah kontribusi saya sendiri untuk upaya ini:
Gagasan dasar: Anda membuat file JSON di root proyek yang memetakan file folder Anda ke nama-nama singkat (atau menggunakan automapper-use untuk melakukannya untuk Anda). Anda kemudian dapat meminta file / modul Anda menggunakan nama-nama itu. Seperti itu:
Jadi begitulah.
sumber
Yang ingin saya lakukan adalah memanfaatkan bagaimana simpul memuat dari direktori node_module untuk ini.
Jika seseorang mencoba memuat modul "hal", ia akan melakukan sesuatu seperti
Node kemudian akan mencari direktori 'thing' di direktori 'node_module'.
Karena node_module biasanya merupakan akar dari proyek, kita dapat meningkatkan konsistensi ini. (Jika node_module tidak di root, maka Anda memiliki sakit kepala yang disebabkan sendiri untuk ditangani.)
Jika kita masuk ke direktori dan kemudian mundur, kita bisa mendapatkan jalur yang konsisten ke root dari proyek node.
Maka jika kita ingin mengakses direktori / happy, kita akan melakukan ini.
Meskipun ini sedikit hacky, namun saya merasa jika fungsionalitas dari bagaimana load node_modules berubah, akan ada masalah yang lebih besar untuk dihadapi. Perilaku ini harus tetap konsisten.
Untuk memperjelas, saya melakukan ini, karena nama modul tidak masalah.
Saya menggunakannya baru-baru ini untuk angular2. Saya ingin memuat layanan dari root.
sumber
src/app/my.service
, Anda juga dapat mengonfigurasi VSC untuk menggunakan impor non-relatif untuk file skrip.Saya menulis paket kecil ini yang memungkinkan Anda memerlukan paket dengan jalur relatifnya dari root proyek, tanpa memperkenalkan variabel global atau default simpul utama
https://github.com/Gaafar/pkg-require
Ini berfungsi seperti ini
sumber
Hanya ingin menindaklanjuti jawaban hebat dari Paolo Moretti dan Browserify. Jika Anda menggunakan transpiler (misalnya, babel, naskah) dan Anda memiliki folder terpisah untuk sumber dan kode yang diubah seperti
src/
dandist/
, Anda bisa menggunakan variasi solusi sebagainode_modules
Dengan struktur direktori berikut:
Anda kemudian dapat membiarkan babel dll untuk mengubah
src
direktori kedist
direktori.symlink
Dengan menggunakan symlink, kita dapat menghilangkan beberapa level sarang:
Peringatan dengan babel --copy-file tersebut
--copy-files
Benderababel
tidak berurusan dengan symlink baik. Mungkin terus bernavigasi ke..
symlink dan secara sembunyi-sembunyi melihat file tanpa akhir. Solusinya adalah dengan menggunakan struktur direktori berikut:Dengan cara ini, kode di bawah
src
masih akanapp
diselesaikansrc
, sedangkan babel tidak akan melihat symlink lagi.sumber
Saya mencari kesederhanaan yang sama persis untuk meminta file dari level apa pun dan saya menemukan modul-alias .
Cukup instal:
Buka file package.json Anda, di sini Anda dapat menambahkan alias untuk path Anda, misalnya
Dan gunakan alias Anda hanya dengan:
sumber
saya membuat modul simpul yang disebut "rekiure"
memungkinkan Anda untuk meminta tanpa menggunakan jalur relatif
itu super mudah digunakan
sumber
Kami akan mencoba cara baru untuk mengatasi masalah ini.
Mengambil contoh dari proyek lain yang diketahui seperti musim semi dan guice, kita akan mendefinisikan objek "konteks" yang akan berisi semua pernyataan "memerlukan".
Objek ini kemudian akan diteruskan ke semua modul lain untuk digunakan.
Sebagai contoh
Ini mengharuskan kami untuk menulis setiap modul sebagai fungsi yang menerima opt, yang menurut kami merupakan praktik terbaik.
dan kemudian Anda akan merujuk pada konteks alih-alih membutuhkan barang.
var module1Ref = context.moduel1;
Jika mau, Anda dapat dengan mudah menulis lingkaran untuk melakukan pernyataan yang diperlukan
Ini akan membuat hidup lebih mudah ketika Anda ingin mengejek (tes) dan juga memecahkan masalah Anda di sepanjang jalan sambil membuat kode Anda dapat digunakan kembali sebagai sebuah paket.
Anda juga dapat menggunakan kembali kode inisialisasi konteks dengan memisahkan deklarasi kacang darinya. misalnya,
main.js
file Anda bisa terlihat seperti ituMetode ini juga berlaku untuk perpustakaan eksternal, tidak perlu membuat kode nama mereka setiap kali kita memerlukannya - namun itu akan memerlukan perlakuan khusus karena ekspor mereka bukan fungsi yang mengharapkan konteks ..
Kemudian kita juga dapat mendefinisikan kacang sebagai fungsi - yang akan memungkinkan kita untuk
require
modul yang berbeda sesuai dengan lingkungan - tetapi itu keluar dari lingkup utas ini.sumber
Saya mengalami masalah dengan masalah yang sama ini, jadi saya menulis sebuah paket bernama include .
Sertakan pegangan yang mencari tahu folder root proyek Anda dengan cara menemukan file package.json Anda, kemudian melewati argumen path yang Anda berikan ke asli memerlukan () tanpa semua kekacauan path relatif. Saya membayangkan ini bukan sebagai pengganti untuk memerlukan (), tetapi alat untuk membutuhkan penanganan file atau pustaka non-paket / non-pihak ketiga. Sesuatu seperti
Semoga ini bermanfaat.
sumber
Jika file entry point js aplikasi Anda (yaitu yang Anda jalankan "node" aktif) ada di direktori root proyek Anda, Anda dapat melakukannya dengan sangat mudah dengan modul npath rootpath . Cukup instal melalui
... lalu di bagian paling atas dari file entry point js, tambahkan:
Sejak saat itu semua panggilan yang membutuhkan sekarang relatif terhadap root proyek - misalnya
require('../../../config/debugging/log');
menjadirequire('config/debugging/log');
(di mana folder config berada di root proyek).sumber
Dalam garis sederhana, Anda dapat memanggil folder Anda sendiri sebagai modul:
Untuk itu kita perlu: modul global dan app-module-path
di sini "App-module-path" adalah modul, itu memungkinkan Anda untuk menambahkan direktori tambahan ke jalur pencarian modul Node.js Dan "global" adalah, apa pun yang Anda lampirkan ke objek ini akan b tersedia di mana saja di aplikasi Anda.
Sekarang lihat cuplikan ini:
__dirname adalah direktori simpul yang sedang berjalan. Anda dapat memberikan jalur Anda sendiri di sini untuk mencari jalur untuk modul.
sumber