Bagaimana cara mengimpor modul global di Node? Saya mendapatkan "Kesalahan: Tidak dapat menemukan modul <module>"?

145

Saya mencoba mengatur Node di Mac OSX Lion. Semuanya sepertinya berfungsi dengan baik, tetapi sepertinya saya tidak dapat mengimpor modul apa pun dari folder modul global saya. Saya mendapatkan kesalahan,

Error: Cannot find module <module>

Jika saya menjalankan ini node -e require.paths:, respons yang saya dapatkan adalah:

[ '/usr/local/lib/node_modules',
  '/Users/Me/.node_modules',
  '/Users/Me/.node_libraries',
  '/usr/local/Cellar/node/0.4.12/lib/node' ]

Yang benar, modul saya memang diinstal di / usr / local / lib / node_modules. Ketika saya mencoba dan menjalankan skrip, saya mendapatkan ini:

Error: Cannot find module 'socket.io'
    at Function._resolveFilename (module.js:326:11)
    at Function._load (module.js:271:25)
    at require (module.js:355:19)
    at Object.<anonymous> (/Users/Me/node/server.js:2:10)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)

.Bash_profile saya terlihat seperti ini:

export PATH=/usr/local/mysql/bin:$PATH
export NODE_PATH=/usr/local/lib/node_modules
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/mysql/lib/"

Sangat menghargai bantuan, saya tidak tahu mengapa saya tidak bisa mengimpor perpustakaan.

Hanpan
sumber
1
Anda tahu bahwa ini bukanlah cara yang disukai untuk melakukan sesuatu, bukan?
thejh
1
Bisakah Anda menguraikan? Apakah maksud Anda saya seharusnya tidak menginstal perpustakaan ke folder global saya?
Hanpan
3
@Hanpan: Cara yang disukai adalah menginstal modul yang ingin Anda gunakan via require () secara lokal.
thejh
1
Jawaban yang lebih baik dan lebih diperbarui (yang tidak bergantung pada npm link) dapat ditemukan di sini: stackoverflow.com/a/15646750/2671392
GGG
1
Saya sekolah tua dan terbiasa memasang perpustakaan di lokasi global. Saya belum pernah melihat alasan yang meyakinkan untuk banyak menggunakan instalasi perpustakaan lokal. Kelas mongodb yang saya ambil akan berakhir di suatu tempat di dekat seratus proyek kecil pada saat kami selesai, masing-masing berisi sebagian besar duplikat perpustakaan - mongodb, express, konsolidasi, dll. Perpindahan ke bahasa interaktif meninggalkan setoran perpustakaan lokal di semua tempat. Saya harus memiliki ribuan lib Scala di repositori Scala lokal. Meteor Ditto, asyik dan ruby.
Stephen W. Wright

Jawaban:

116

Jika Anda menggunakan npm> = 1.0, Anda dapat menggunakan npm link <global-package>untuk membuat tautan lokal ke paket yang sudah diinstal secara global. ( Peringatan: OS harus mendukung symlink. )

Namun, ini tidak datang tanpa masalah.

tautan npm adalah alat pengembangan. Ini luar biasa untuk mengelola paket di kotak pengembangan lokal Anda. Tetapi penggelaran dengan tautan npm pada dasarnya menanyakan masalah, karena membuatnya sangat mudah untuk memperbarui berbagai hal tanpa menyadarinya.

Sebagai alternatif, Anda dapat menginstal paket secara lokal maupun global.

Untuk informasi tambahan, lihat

Tadeusz Wójcik
sumber
69
Saya membaca ini dan tidak bisa mempercayai mata saya. Jadi jika saya menginstal, katakan express, dan kemudian memiliki 20 proyek untuk dibangun di atas express, saya perlu menginstalnya 20 kali, untuk masing-masing, dalam setiap folder proyek, berulang-ulang? Saya tidak punya banyak pengalaman dengan manajer paket tetapi ini agak menyebalkan ...
treznik
25
Itu benar, dan jika Anda memikirkannya, itu masuk akal. Mengelola dependensi Anda secara lokal membuat semuanya tetap serba lengkap dan memungkinkan Anda menentukan versi tertentu dari dependensi untuk proyek apa pun (mis. Project foo membutuhkan express 2.x, sedangkan project bar dapat menggunakan express 3 beta).
grahamb
43
Saya berjuang untuk memahami logika ini untuk sementara waktu juga, tetapi setelah menonton teman Ruby saya berjuang dengan pembaruan paket global, berdebat tentang permata dan sering kali tidak pernah memutakhirkan, saya mengakui bahwa menginstal dependensi secara lokal adalah satu-satunya cara yang waras untuk dilakukan. manajemen paket .
timoxley
3
Saya ingin menggambar paralel antara situasi ini dan perpustakaan yang menghubungkan statis vs dinamis yang berkaitan dengan distribusi perangkat lunak. Pertimbangkan bahwa hampir semua Aplikasi yang didistribusikan di iOS App Store harus secara taut menghubungkan ketergantungan yang tidak disediakan oleh iOS SDK. Mengapa ini dilakukan? Neraka ketergantungan global adalah hal yang sangat nyata.
Steven Lu
1
Ini juga merupakan pemahaman saya bahwa npmcache (yang tinggal di ~/.npm) akan membuat proses instalasi ulang dilakukan di lokasi Anda yang berbeda.
Steven Lu
85

Node.js menggunakan variabel lingkungan NODE_PATHuntuk memungkinkan menentukan direktori tambahan untuk dimasukkan dalam jalur pencarian modul. Anda dapat menggunakan npmdirinya sendiri untuk memberi tahu Anda di mana modul global disimpan dengan npm root -gperintah. Jadi dengan menyatukan keduanya, Anda dapat memastikan modul global dimasukkan dalam jalur pencarian Anda dengan perintah berikut (di Linux-ish)

export NODE_PATH=$(npm root --quiet -g)

Joel B
sumber
3
Terima kasih atas NODE_PATHpetunjuk variabel lingkungan. Itu banyak membantu!
rekire
7
Ini harus menjadi komentar teratas
Adam Prax
Saya harus mengatur NODE_PATHke jalur posix yang setara untuk membuat npm bekerja pada MSYS2. Terima kasih.
Joyce Babu
Bekerja dengan Windows dan Git bash juga. Sempurna. :-)
inf3rno
Ini membuat .node_modulesfolder Anda dapat dicari, tetapi untuk mengimpor modul menggunakan require(), mereka harus tetap diinstal di direktori proyek lokal Anda (atau sebagai alternatif, ditautkan menggunakan npm link). Modul global tidak dapat diimpor dalam proyek, hanya binari / skrip yang dapat dijalankan dari sana.
Prahlad Yeri
65

Anda dapat menggunakan tautan npm untuk membuat tautan simbolis ke paket global Anda di folder proyek Anda.

Contoh:

$ npm install -g express
$ cd [local path]/project
$ npm link express

Yang dilakukan adalah membuat folder node_modules lokal dan kemudian membuat symlink express -> [direktori global] / node_modules / express yang kemudian dapat diselesaikan dengan require('express')

Nick Sotiros
sumber
Apakah cross-OS ini kompatibel?
UpTheCreek
Versi Windows yang lebih baru mendukungnya sejak versi ini: github.com/npm/npm/commit/... Untuk versi Windows yang lebih lama, coba npmjs.com/package/npm-junction
Alex
22

Instal paket apa pun secara global seperti di bawah ini:

$ npm install -g replace  // replace is one of the node module.

Karena modul pengganti ini dipasang secara global, maka jika Anda melihat folder modul simpul Anda, Anda tidak akan melihat modul pengganti di sana dan jadi Anda tidak dapat menggunakan paket ini menggunakan memerlukan ('ganti').

karena dengan mengharuskan Anda dapat menggunakan hanya modul lokal yang ada di folder modul simpul Anda.

Sekarang untuk menggunakan modul global Anda harus menautkannya dengan jalur modul simpul menggunakan perintah di bawah ini.

$ npm link replace

Sekarang kembali dan lihat folder modul simpul Anda, Anda sekarang dapat melihat ganti modul di sana dan dapat menggunakannya dengan memerlukan ('ganti') di aplikasi Anda karena terhubung dengan modul simpul lokal Anda.

Tolong beri tahu saya jika diperlukan klarifikasi lebih lanjut.

pengguna5341372
sumber
14

Anda dapat menggunakan persyaratan dengan jalur ke direktori modul global sebagai argumen.

require('/path/to/global/node_modules/the_module');

Di mac saya, saya menggunakan ini:

require('/usr/local/lib/node_modules/the_module');

Bagaimana menemukan di mana modul global Anda berada? -> Di mana npm menginstal paket?

ling
sumber
7

Mengatur variabel lingkungan NODE_PATH untuk menunjuk ke node_modulesfolder global Anda .

Di Windows 7 atau lebih tinggi pathnya adalah sesuatu seperti %AppData%\npm\node_modulessementara di UNIX bisa jadi seperti /home/sg/.npm_global/lib/node_modules/tetapi tergantung pada konfigurasi pengguna.

Perintah npm config get prefix dapat membantu menemukan jalan mana yang benar.

Dalam sistem UNIX Anda dapat mencapainya dengan perintah berikut:

export NODE_PATH=`npm config get prefix`/lib/node_modules/
Ben Xu
sumber
0

Saya menggunakan Docker. Saya mencoba membuat gambar buruh pelabuhan yang memiliki semua dependensi simpul saya diinstal, tetapi dapat menggunakan direktori aplikasi lokal saya pada waktu menjalankan wadah (tanpa mencemari itu dengan direktori atau tautan node_modules). Ini menyebabkan masalah dalam skenario ini. Solusi saya adalah meminta dari jalur yang tepat di mana modul, misalnya memerlukan ('/ usr / local / lib / node_modules / socket.io')

Darin London
sumber
-1

require.paths sudah ditinggalkan.

Buka folder proyek Anda dan ketik

npm install socket.io

yang harus menginstalnya di folder ./node_modules lokal tempat simpul akan mencarinya.

Saya menyimpan barang-barang saya seperti ini:

cd ~/Sites/
mkdir sweetnodeproject
cd sweetnodeproject
npm install socket.io

Buat file app.js

// app.js
var socket = require('socket.io')

sekarang jalankan aplikasi saya

node app.js

Pastikan Anda menggunakan npm >= 1.0dan node >= 4.0.

Jamund Ferguson
sumber
8
Dia bertanya tentang menggunakan paket npm yang terinstal secara global.
UpTheCreek
@ Jamund. Anda menunjukkan cara menggunakan paket yang diinstal secara lokal, tetapi pertanyaan awal adalah tentang yang global.
Vitaliy Markitanov