NodeJS genel bir modül / paket gerektirir


160

Global olarak yüklemeye çalışıyorum ve sonra kullanmak foreverve bunun forever-monitorgibi:

npm install -g forever forever-monitor

Her zamanki çıktıyı ve dosyaları global yola kopyalayan işlemleri görüyorum, ancak sonra denemediğimde require("forever");modülün bulunmadığını söyleyen bir hata alıyorum.

Hem düğüm hem de npm'in en son sürümünü kullanıyorum ve küresel vs yerel kurulumda npm'nin yaptığı değişikliği zaten biliyorum, ama gerçekten her projeye yerel olarak yüklemek istemiyorum ve olmayan bir platform üzerinde çalışıyorum Bu linkyüzden npm linkglobal kurulumdan sonra benim için mümkün değil.

Sorum şu: neden global olarak kurulmuş bir pakete ihtiyaç duymuyorum? Bu bir özellik mi yoksa hata mı? Yoksa yanlış bir şey mi yapıyorum?

Not: Sadece berraklaştırmak için: Yerel olarak kurmak istemiyorum.




bu yüzden ~/.config/yarn/globaliplik için
localhostdotdev

Yanıtlar:


216

Node.js'de, requir, genel modüllerin yüklü olduğu klasöre bakmaz.

NODE_PATH ortam değişkenini ayarlayarak bunu düzeltebilirsiniz. Linux'ta bu:

export NODE_PATH=/usr/lib/node_modules

Not: Bu, global modüllerinizin gerçekte nereye kurulduğuna bağlıdır.

Bkz . Genel klasörlerden yükleme .


24
Ubuntu 13.10 makinemde, modüllerin global yolu burada gösterilenden farklı. Onun export NODE_PATH=/usr/local/lib/node_modulesyerine kullanmak zorunda kaldım .
Drew Noakes

11
Windows 7/8 kullanıyorsanız ve Düğüm'ün yükleme varsayılanlarından herhangi birini geçersiz kılmadıysanız, NODE_PATHortam değişkenini olarak ayarlamak C:\Users\{USERNAME}\AppData\Roaming\npm\node_modulesbüyük olasılıkla işe yarayacaktır.
Wes Johnson

5
@WesJohnson %AppData%\npm\node_modulesWindows 10'da çalışacak
theblang

6
Ayarladıysam NODE_PATH, global ve yerel modülleri aynı anda kullanabilir miyim?
Paulo Oliveira

6
Alternatif olarak statik bir yol yerine, yani NVM kullanıyorsanız:NODE_PATH=$(npm root -g)
holmberd

98

Paketi global olarak yükledikten sonra yerel projeyi global pakete bağlamanız gerekir

npm install express -g
cd ~/mynodeproject/
npm link express  

Buraya bakın


2
Bağlantıyı desteklemeyen bir platformda çalışıyorum (sorumu belirttiği gibi) blog.nodejs.org/2011/04/06/npm-1-0-link
alexandernst

1
hangi platformu kullanıyorsun
user568109

1
Gerçekten link ile uğraşmak istemiyorum (ne de sembolik linkler). Sadece paketleri global olarak kurmak istiyorum. NPM'nin bundan kaçınmak için yeniden tasarlandığını biliyorum, ancak böyle bir şey elde etmek ne kadar zor olabilir?
alexandernst

13
Bir projem yoksa ne olur? Söyle ~/some-stand-alone-random-nodejs-test.js. Giriş klasörümü proje dizinine dönüştürmek istemiyorum. Her küçük deneme için yeni klasörler oluşturmak istemiyorum.
AnnanFay

1
Windows 8.1'de mükemmel çalıştı. Düğüm komut satırı cd'sinden projelerimin yerel node_modules klasörüne sonra yürütülür. npm link <module>Ardından projelerinizin node_module klasöründe genel düğüm modülüne başvuruda bulunan bir kısayol (bağlantı) göreceksiniz .
dynamiclynk

26

Büyücülük için özür dilerim ama küresel olarak kurulmuş modüllere sabit kodlanmış yollar belirleyebiliyorum:

var pg = require("/usr/local/lib/node_modules/pg");

Bu mükemmel değil ama Unity3d proje dizininde bulunan tüm javascript "derlemek" çalıştığını düşünüyor ben gerçekten herhangi bir paket yükleyemezsiniz.


4
Unity3D, JavaScript'i desteklemez. Aldatıcı olarak “JavaScript” olarak pazarlanan Boo yorumlayıcısı / derleyicisi için JS benzeri bir sözdizimini destekler (Boo, .NET için Python benzeri bir dildir) . Unity'nin desteklediği dil için en doğru ad UnityScript'tir . Aynı dile yakın olmadığından, web veya Node.js için yazılmış JS'nin hiçbiri Unity'de çalışmayacaktır. Resmi Unity wiki'deki farklılıklar hakkında çok daha fazla bilgi: wiki.unity3d.com/index.php/UnityScript_versus_JavaScript
Slipp D. Thompson 12:00 '

19

Bu eski bir soru olduğunu biliyorum, ama ben semverbir preinstallkomut dosyası kullanarak bazı sürüm denetimi yapmaya çalışırken bu koştu package.json. Yüklü herhangi bir yerel modüle güvenemeyeceğimi bildiğim için, bunu semverglobal node_modulesklasörden istemek için kullandım ( npmbuna bağlı olarak orada olduğunu biliyorum):

function requireGlobal(packageName) {
  var childProcess = require('child_process');
  var path = require('path');
  var fs = require('fs');

  var globalNodeModules = childProcess.execSync('npm root -g').toString().trim();
  var packageDir = path.join(globalNodeModules, packageName);
  if (!fs.existsSync(packageDir))
    packageDir = path.join(globalNodeModules, 'npm/node_modules', packageName); //find package required by old npm

  if (!fs.existsSync(packageDir))
    throw new Error('Cannot find global module \'' + packageName + '\'');

  var packageMeta = JSON.parse(fs.readFileSync(path.join(packageDir, 'package.json')).toString());
  var main = path.join(packageDir, packageMeta.main);

  return require(main);
}

Bu yaklaşımı seviyorum çünkü bu, kullanmak için herhangi bir özel modülün kurulmasını gerektirmiyor.

NODE_PATHBaşkalarının önerdiği gibi bir çözümle gitmedim, çünkü bunu npm installprojem için çalıştırmadan önce ek yapılandırma / kurulum gerektirmeden kimsenin makinesinde çalışmak istedim .

Bunun kodlanması sırasında, yalnızca üst düzey modülleri (kullanılarak kurulur npm install -g ...) veya gerekli olan modülleri npm( dependenciesburada listelenen : https://github.com/npm/npm/blob/master/package.json ) bulması garanti edilir . NPM'nin daha yeni bir sürümünü kullanıyorsanız, node_modulesşu anda klasörler için daha düz bir yapı olduğundan global olarak yüklenmiş diğer paketlerin bağımlılıklarını bulabilir .

Umarım bu birisi için yararlıdır.


19

Gereğince belgeleri , node.js varsayılan olarak aşağıdaki konumlarda arayacaktır:

  1. NODE_PATHOrtam değişkeninde belirtilen yol .

    Not: NODE_PATHortam değişkeni, iki nokta ile ayrılmış mutlak yolların listesine ayarlanır.

  2. Geçerli node_modulesklasör. (yerel)

  3. $HOME/.node_modules (Global)

    Not: $HOMEkullanıcının ana dizinidir.

  4. $HOME/.node_libraries (Global)
  5. $PREFIX/lib/node (Global)

    Not: $PREFIXNode.js yapılandırılmıştır node_prefix.

    Geçerli değerini kontrol etmek için şunu node_prefixçalıştırın:

    node -p process.config.variables.node_prefix

    Not: Önek --prefixderleme sırasında parametrelere karşılık gelir ve görecelidir process.execPath. Komuttaki değerle karıştırmamak npm config get prefix. kaynak

Verilen modül bulunamazsa, bu yukarıdaki konumlardan birinde bulunmadığı anlamına gelir.

Modüllerin yüklendiği genel kök klasörünün konumu şu şekilde yazdırılabilir: npm root -g(varsayılan olarak npmrcdosyada geçersiz kılınmadıkça yol çalışma zamanında hesaplanır ).

Çözüm

Aşağıdaki geçici çözümleri deneyebilirsiniz:

  • NODE_PATHOrtam değişkeninde global modül konumunuzu belirtin . Örneğin

    echo 'require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node

    Değerini test etmek ve yazdırmak için şunu NODE_PATHçalıştırın:

    echo 'console.log(process.env.NODE_PATH); require("forever")' | NODE_PATH="$(npm root -g):$NODE_PATH" node 
  • Daha kalıcı bir çözüm için, $HOME/.node_modulesşu komutu çalıştırarak genel kullanıcı klasörünüzü kök klasöre yönlendirin:

    ln -vs "$(npm root -g)" "$HOME"/.node_modules

    Sonra: echo 'require("forever")' | nodecommand ile tekrar test edin .

  • Komut dosyasını çağırmadan önce geçerli klasörü geçici olarak uzantının yüklendiği yere değiştirin. Örneğin

    npm install -g forever
    cd "$(npm root -g)"
    echo 'require("forever")' | node
    cd -
  • npmUserconfig dosyasında (bkz. npm help 5 npmrc) Veya userconfigparam ( --prefix) ile genel kurulum hedefini yapılandırın .

    Geçerli yapılandırma görüntülemek için çalıştırın: npm config list.

    Düzenlemek için geçerli yapılandırma, çalıştırın: npm config edit.

  • Arama yaparken düğüm modülleri konumunun tam yolunu belirtin require(). Örneğin

    require("/path/to/sub/module")
  • Paketi özel bir konuma yükleyin, ör.

    npm install forever -g --prefix "$HOME"/.node_modules

    Ancak, kurulum devam edecek ~/.node_modules/lib/node_modules/, bu nedenle konumun hala eklenmesi gerekiyor.

    Bkz. Npm yerel kurulum paketi özel konuma

  • Genel klasör konumundan geçerli klasörde bir sembolik bağlantı oluşturun . Örneğin

    npm link forever

4'e benzer. Geçerli node_modules klasörü. (yerel) 3'ten önceliklidir. $ PREFIX / lib / node (global)
Király István

Yerel node_modules klasörleri her zaman global klasörlere göre önceliklidir!
Király István

14

requiregBu sorunu çözmek için paketi kullanabilirsiniz :

var forever = require('requireg')('forever')

hile yapacak.

Ayrıca, başka bir modül var, global-npmsadece küresel olanı kullanmaya özgü olsa npmda, kısa koda bakabilir ve tekniğin nasıl çalıştığını görebilirsiniz.


ilginç, ama NODE_PATH yöntemi muhtemelen daha kanonik
Alexander Mills

güzelliği NODE_PATHde, herhangi bir kodu değiştirmenize gerek olmamasıdır. (kullanım durumum, npm installher biri için koşmak istemediğim ve aynı zamanda node_modulesdizin sağlamalarını istemediğim bir çok öğrenci projesini derecelendiriyor ).
amenthes

Hayır, hile yapmayacak çünkü requiregilk etapta talep edemezsiniz , bu bütün mesele.
thisismydesign

6

Büyük modüllere bağımlı CLI yardımcı programları için, örneğin puppeteer, bir npm root -gmodül oluşturmayı ve bunu global modülü gerektirecek şekilde kullanmayı seviyorum .

try {
  const root = require('child_process').execSync('npm root -g').toString().trim()
  var puppeteer = require(root + '/puppeteer')
} catch (err) {
  console.error(`Install puppeteer globally first with: npm install -g puppeteer`)
  process.exit(1)
}

3

Bu satırı .profiledosyanıza koyabilirsiniz :

dışa aktar NODE_PATH = "$ (npm config get öneki) / lib / node_modules"

Bu nodeküresel yolu kullanacaktır.


1
Hayır. Bu, küreselleşmenin genel yoludur node_modules. Bu eski bir cevap ama bunu dokümantasyonda bir yerden aldığımı hatırlıyorum. Her neyse, bilgisayarımda (2020'de) global npm node_modulesdizini usr/lib/node_modules. Her neyse, güveniyorum npm config get prefixçünkü global bir paket kurulduğunda npm tarafından global olarak kullanılıyor, bu yüzden doğru olmalı.
Luis Paulo

1
Her iki durumda da (ilk cevabımda bunu söylemedim, çünkü Node.JS'de çok deneyimli değildim), bir programda global olarak yüklenmiş paketleri kullanmak bir kenar kullanım örneğidir ve nadiren yapılmalıdır çünkü bir projede Proje, VCS'ye bağlı olduğunda ve package.jsondosyada veya yarn.lock/ dosyasında belirli bir bağımlılığın olmaması nedeniyle başka bir ortamda klonlandığında karşılaşılan sorunlar package-lock.json.
Luis Paulo

1
Ah! Şimdi anlıyorum. PATOD ile NODE_PATH'ı yanlış anladığınıza inanıyorum. PATH, bir kabuğun yürütülebilir dosyaları arayacağı yerdir. NODE_PATH, düğümün paketleri arayacağı yerdir. Bir node_modulesklasör için geçerli dizine bakarak başlayacaktır , o zaman üst, daha sonra üst, ... node_moduleso modülü içeren bir klasör bulana kadar . Ancak, bir paketi genel olarak yüklerseniz node_modules, komut dosyasının geçerli dizininin üstündeki herhangi bir klasörün içinde olmaz, bu nedenle düğümün paketleri arayacağı bir yedek olarak NODE_PATH kullanırsınız.
Luis Paulo

1
ahahahah @ Louis Paulo tamamen haklısın !! Üzgünüm! Karışıklığı, güzel işi ve teşekkür etmeyi önlemek için bazı yorumlarımı silmeye çalışacağım
Ryan Taylor

@Ryan Taylor Yorumlar ve soruları çözüldükten sonra silmemelisiniz çünkü başka biri aynı sorulara sahip olabilir. Şimdi yorumlarda bir monolog vardı gibi görünüyor! ahahahah
Luis Paulo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.