Memiliki project_name/node_modules sebagai symlink?

Terkait: folder node_modules tunggal untuk beberapa proyek

Jika npm install -g semuanya tidak disarankan, dan saya tidak ingin menautkan masing-masing modul, bisakah saya menghubungkan <some project>/node_modules ke direktori umum untuk dibagikan oleh banyak proyek?


person prusswan    schedule 27.03.2016    source sumber


Jawaban (1)


Node dapat menangani symlink dengan baik. Cara mencapainya bergantung pada beberapa tujuan Anda. Yang paling penting adalah: pengalaman apa yang ingin Anda miliki untuk pengembang lain yang mengunduh proyek Anda dari kontrol versi?

Saat merancang pengalaman ini, akan sangat membantu jika membaca tentang algoritme pemuatan modul Node, untuk mendapatkan wawasan tentang apa yang mungkin dilakukan.

Secara umum, rekomendasi saya adalah untuk tidak khawatir dengan duplikasi ketergantungan antar proyek. "Memperbaiki" hal ini tidak sebanding dengan biaya pemeliharaan, yang mencakup kemacetan ketergantungan (konflik kebutuhan subproyek) dan memerlukan alat khusus dalam beberapa kasus untuk memperhitungkan struktur khusus Anda.

Dengan tidak adanya peringatan tersebut, bagaimana kita melakukannya? Cara paling sederhana adalah dengan membuat proyek super yang merangkum berbagai subproyek. Subproyek akan secara efektif mewarisi ketergantungan proyek super.

superproject/
|-- node_modules/
|   +-- socket.io/
|-- package.json
|-- subprojectA/
|   |-- node_modules/
|   |   +-- browserify/
|   |-- package.json
|   +-- app/
|       +-- client.js
+-- subprojectB/
    |-- node_modules/
    |   +-- express/
    |-- package.json
    +-- lib/
        +-- server.js

Struktur ini berfungsi seperti yang Anda harapkan, file dalam subproyek dapat require() modulnya sendiri dan modul apa pun di superproject/node_modules, tetapi file tersebut tidak akan dengan mudah require() modul dalam subproyek saudaranya (masih memungkinkan untuk melakukannya melalui jalur eksplisit). Dengan kata lain, client.js dapat require() melakukan browserify dan socket.io tanpa jalur, tetapi harus menggunakan jalur ke require() express.

Aspek penting dari hal ini adalah npm melakukan pencarian "menemukan" untuk package.json dan menangani modul di direktori node_modules sebagai saudara dari file tersebut saat menginstal, dll. Ini berarti direktori kerja Anda saat ini harus superproject untuk memasang modul di dalamnya, kecuali subproyek Anda tidak memiliki file package.json.

person Seth Holladay    schedule 27.03.2016
comment
Ketergantungan yang diduplikasi merupakan masalah besar, karena file memakan cukup banyak ruang bahkan untuk proyek yang sangat kecil, dan juga menyebabkan pemborosan bandwidth secara tidak langsung ketika menyiapkan proyek baru yang (kebanyakan) menggunakan ketergantungan yang sama. - person prusswan; 27.03.2016
comment
Saya bisa memahami keinginan itu. Namun menurut saya Anda akan mendapati bahwa menggabungkan berbagai proyek secara erat dengan cara ini akan menciptakan beban yang berbeda. Di mana Anda tidak dapat memperbarui ketergantungan karena proyek x memerlukan perilaku tertentu. Tetapi Anda benar-benar ingin/perlu memperbaruinya karena proyek y menggunakannya secara berbeda dan memerlukan sesuatu yang baru. Di masa lalu, semua modul npm bersifat global, praktik ini berhenti karena komunitas menyadari bahwa hal itu tidak layak dilakukan. nodejs.org/en/blog/npm /npm-1-0-global-vs-local-installation Meskipun demikian, masih ada cara untuk melakukan modul pseudo-global. - person Seth Holladay; 27.03.2016
comment
Proyek super ini adalah solusi brilian! Terima kasih banyak. Dalam kasus saya, saya sedang mengerjakan beberapa proyek Laravel PHP, yang menggunakan node untuk tugas-tugas pengembangan saja (teguk). Gulp dan require() hanya berfungsi ketika diinstal secara lokal, tetapi menduplikasi 200MB node_modules untuk setiap proyek PHP 5MB sama sekali tidak masuk akal, terutama karena saya sendiri tidak melakukan pengembangan node apa pun. Proyek super ini adalah satu-satunya solusi masuk akal yang saya temukan: Saya dapat memiliki folder laravel-5.2 dengan satu salinan alat yang diperlukan oleh 5.2, bersama dengan semua proyek 5.2, dan seterusnya. Cemerlang! - person Tobia; 06.07.2016
comment
@SethHolladay Orang-orang telah menghadapi masalah ini dan telah berhasil diselesaikan dalam sejarah pengembangan OS. Ada ratusan (jika tidak ribuan) perpustakaan bersama di OS apa pun dan beberapa versi berbeda dari perpustakaan yang sama dapat hidup berdampingan dengan senang hati hanya dengan menggunakan aturan sederhana - sertakan versi tersebut dalam nama perpustakaan. Jadi pengembang yang cerdas akan menggunakan konvensi node_modules/[email protected]/library.js dan kemudian kita tidak perlu berjuang melawan tembok.... - person IVO GELOV; 11.09.2017
comment
@IVOGELOV beberapa versi berbeda dari perpustakaan yang sama dapat hidup berdampingan dengan bahagia - benar, dan npm juga dapat melakukan hal ini. Satu-satunya perbedaan adalah npm memilih untuk menyarangkan dependensi dalam format pohon bila diperlukan, daripada selalu meletakkan semuanya datar dan menduplikasi informasi versi dalam ID modul. Itu berfungsi lebih baik untuk dependensi lokal, dan itu direkomendasikan. Agar dapat berfungsi pada dependensi bersama global, pemuat modul memerlukan informasi versi dalam ID modul. Tapi tidak ada yang mau require('[email protected]'), karena itu hanya ada di satu tempat: package.json - person Seth Holladay; 30.09.2017
comment
@SethHolladay Saya akui bahwa pengalaman saya dengan NPM dan Node saja tidak cukup jadi mohon maafkan saya jika kata-kata saya terdengar bodoh. Di Linux ketika Anda menginstal versi baru dari sebuah perpustakaan, versi lama tidak dihapus tetapi sebuah symlink (yang tidak berisi informasi versi dalam namanya) dibuat untuk menunjuk ke versi terbaru dari perpustakaan tersebut. Namun, jika Anda meningkatkan perpustakaan - versi saat ini tidak disimpan. Dengan demikian konsumen dapat menggunakan versi terbaru (apa pun itu) melalui symlink - atau secara eksplisit menunjuk ke versi perpustakaan yang diinginkan. Dan tugas loader adalah memeriksa package.json - person IVO GELOV; 01.10.2017
comment
@SethHolladay dan tentukan apakah require atau import memerlukan versi tertentu atau versi mana yang terbaru yang diinstal saat ini. Bagi saya juga terlihat kontra-intuitif bahwa NPM menolak bekerja ketika node_modules di folder proyek adalah symlink. - person IVO GELOV; 01.10.2017
comment
node_modules menjadi symlink seharusnya berfungsi dengan baik. Saya belum mengujinya secara khusus, tetapi jika tidak berhasil, sepertinya ada bug. Saya tidak mengetahui adanya pilihan atau batasan desain apa pun yang akan memberikan batasan di mana node_modules tidak boleh berupa symlink. Meski begitu, mungkin npm secara naif menggagalkannya. Adapun tugas loader adalah memeriksa package.json, itu bagus. Sayangnya, ternyata tidak. Kedengarannya seperti solusi yang bagus, dan berpotensi diterapkan di wilayah pengguna. - person Seth Holladay; 02.10.2017
comment
Bukan untuk membajak postingan tetapi saya menghadapi masalah serupa, lihat postingan SO saya di sini, dan telah mencoba solusi membuat symlink dari direktori node-modules eksternal yang meletakkannya di root direktori proyek saya. Maksud saya bukan untuk berbagi direktori node_modules di berbagai proyek tetapi untuk menangani lingkungan terbatas ruang pada disk Raspberry Pi yang dipartisi. - person Brad W; 23.12.2020