Bağımlılıkları package.json kullanarak global olarak ve yerel olarak yükleyin


189

Npm kullanarak -gopsiyonları kullanarak global olarak modülleri kurabiliriz . Bunu package.json dosyasında nasıl yapabiliriz?

Diyelim ki bunlar package.json dosyasındaki bağımlılıklarım

"dependencies": {
    "mongoose": "1.4.0",
    "node.io" : "0.3.3",
    "jquery"  : "1.5.1",
    "jsdom"   : "0.2.0",
    "cron"    : "0.1.2"
  }

Çalıştığımda npm install, yalnızca node.ioglobal olarak yüklenmesini istiyorum , diğerleri ise yerel olarak kurulmalıdır. Bunun için bir seçenek var mı?


11
Yapamazsın. Ancak "preferGlobal": truebir modül için package.json içinde ayarlayabilirsiniz .
Raynos

Evet, <code> preferGlobal </code> hakkında bilgim var, ancak bu tüm bağımlılıkları global olarak yükler ... neyse Teşekkürler! sanırım böyle bir özellik yok ...
Madhusudhan

3
Öyle olduğunu sanmıyorum. Mevcut modülü küresel olarak kurar. Bireysel bağımlılık true olarak ayarlanmışsa, global olarak da kurulabilir. Gerçekten sadece # node.js @isaacs sormak gerekir
Raynos

3
Global kurulumlar bağımlılık cehennemi üretebilir. A paketinin 0.3.3 sürümüne ve B paketinin 0.3.4 sürümüne ihtiyacı olduğunu ve her ikisinin de diğer sürümle çalışmadığını varsayalım. Sonra iki paketi karşılamak için iki makineye ihtiyacınız olacak.
nalply

6
Bu yorumların hiçbiri bana bu konuda yardımcı olur ... sadece bana daha fazla kod göstermek eğer güzel olurdu "preferGlobal":true... gerçekten package.json bunu nereye koymak bilmiyorum. npmjs.org/doc/json.html NPM belgeleri, prefGlobal'ın kendi paketiniz için olduğunu ve bu ayarın kendi paketinizi global olarak kurmasını sağlayacağını söylüyor. Yine de bir rehber gibi görünüyor.
PPPaul

Yanıtlar:


216

Yeni Not: Muhtemelen bunu yapmak istemiyorsunuz veya yapmanız gerekmiyor. Muhtemelen yapmak istediğiniz şey, devDependenciespaket / jj.bson bölümünüzde derleme / test vb. İçin bu tür komut bağımlılıklarını koymaktır . Package.json içindeki bir şeyi her kullandığınızda scriptsdevDependencies komutlarınız (node_modules / .bin içinde) yolunuzdaymış gibi davranır.

Örneğin:

npm i --save-dev mocha # Install test runner locally
npm i --save-dev babel # Install current babel locally

Sonra package.json içinde:

// devDependencies has mocha and babel now

"scripts": {
  "test": "mocha",
  "build": "babel -d lib src",
  "prepublish": "babel -d lib src"
}

Ardından komut isteminizde şunları çalıştırabilirsiniz:

npm run build # finds babel
npm test # finds mocha

npm publish # will run babel first

Ama eğer gerçekten küresel yüklemek istiyorsanız, package.json ait komut bölümünde önceden yükleme ekleyebilirsiniz:

"scripts": {
  "preinstall": "npm i -g themodule"
}

Yani aslında benim npm kurulum tekrar npm kurulum yürütür .. hangi garip ama çalışıyor gibi görünüyor.

Not: Genel npmDüğüm paketi yüklemelerinin gerektiği yerlerde en yaygın kurulumu kullanıyorsanız sorun yaşayabilirsiniz sudo. Bir seçenek, npmyapılandırmanızı değiştirerek bu gerekli değildir:

npm config set prefix ~/npm, ekleyerek $ PATH için $ HOME / npm / bin export PATH=$HOME/npm/bin:$PATHekleyin ~/.bashrc.


3
Bunu çalıştıramadım npm i -g underscore-cli. wd'nin yanlış olduğu konusunda bir uyarı verir. wd çalışma dizini anlamına gelir, sanırım. i manuel olarak komut satırında bunu yapmak sonra işler iyi gitmek, ancak kullanıcı basit birnpm install
PPPaul 25:12

3
PPPaul - Son zamanlarda tekrar bu hileyi denediğimde aynı problemi yaşadım. Belki de kurulumum şimdi farklı veya sadece belirli modüllerle çalışıyor. Aksi takdirde npm ile bir şey değişti sanırım?
Jason Livesay

9
Buna ek olarak, paketin zaten kurulu olup olmadığını önceden kontrol edebilirsiniz: npm list module -g || npm install module -gnpm düzgün çıkış değerleri döndürür.
m90

3
@CMCDragonkai: Bu gerçekten ayrı bir soru olmalı. Ancak, komutlarınızı bir komut dosyasına koyarsınız ve komut dosyasını yürütülecek komut olarak belirtirsiniz (beğen "preinstall" : "scripts/preinstall.sh").
Hepimiz Monica

1
@CMCDragonkai &&, örneğinnpm install -g bower && npm install -g grunt-cli
Matsemann

12

Aşağıda açıklanan dezavantajlar nedeniyle , kabul edilen cevabı takip etmenizi tavsiye ederim :

npm install --save-dev [package_name]Aşağıdaki komut dosyalarını kullanın ve çalıştırın:

$ npm run lint
$ npm run build
$ npm test

Orijinal ama önerilmeyen cevabım şöyle.


Genel yükleme kullanmak yerine, paketi devDependencies( --save-dev) öğenize ekleyebilir ve ardından ikili dosyayı projenizin içindeki herhangi bir yerden çalıştırabilirsiniz:

"$(npm bin)/<executable_name>" <arguments>...

Senin durumunda:

"$(npm bin)"/node.io --help

Bu mühendisnpm-exec kısayol olarak bir takma ad sağladı . Bu mühendis adlı bir kabuk betiği kullanır env.sh. Ancak $(npm bin), herhangi bir ek dosya veya kurulumdan kaçınmak için doğrudan kullanmayı tercih ederim .

Her bir çağrıyı biraz daha büyük hale getirmesine rağmen, sadece çalışarak şunları engellemelidir:

  • global paketlerle potansiyel bağımlılık çatışmaları (@nalply)
  • ihtiyaç sudo
  • npm öneki ayarlama gereği (yine de bir tane kullanmanızı öneririm)

Dezavantajları:

  • $(npm bin) Windows üzerinde çalışmaz.
  • Geliştirici ağacınızdaki daha derin araçlar npm binklasörde görünmez . ( Bulmak için npm-run veya npm- kurun .)

Jason'ın yukarıda da gösterdiği gibi, ortak görevleri (bina ve küçültme gibi) sizin "komut dosyaları" bölümüne yerleştirmek daha iyi bir çözüm gibi görünüyor .package.json


Gözlerinde farklı bir takma ad ekleyin .bashrckolayca eklemek için bin/sizin için dizin PATHortam değişkeni: alias nodebin='export PATH=$(npm bin)/:$PATH'. Yürüt nodebinve daha sonra komutlarınızı her zamanki gibi yazabilirsiniz.
gitaarik

Takımlar için neden işe yaramayacağını bilmiyorum. Tabii ki ayarlamanız gerekiyor ve takma adı kullanmak istemiyorsanız, bu sizin seçiminizdir. Ama bunu bir takımda kullanmak zarar veremez.
gitaarik

9

Bu biraz eski ama bu yüzden koştum çözüm burada koştu.

Sorun:

Geliştirme ekibimiz AngularJS / Bootstrap'e geçirdiğimiz birçok .NET web uygulaması ürününü bulundurmaktadır. VS2010, özel yapım süreçlerine kolayca borç vermez ve geliştiricilerim rutin olarak ürünlerimizin çoklu sürümleri üzerinde çalışıyorlar. VCS'imiz Subversion (Biliyorum, biliyorum. Git'e geçmeye çalışıyorum ama sinir bozucu pazarlama ekibim çok zorlu) ve tek bir VS çözümü birkaç ayrı proje içerecek. Aynı Düğüm paketlerini (yudum, bower vb.) Aynı makineye birkaç kez kurmak zorunda kalmadan geliştirme ortamlarını başlatmak için ortak bir yönteme sahip olmam gerekiyordu.

TL; DR:

  1. Bir .NET ürünü için yerel olarak gerekli tüm paketlerin yanı sıra genel Düğüm / Bower geliştirme ortamını yüklemek için "npm install" gerekir.

  2. Global paketler yalnızca önceden kurulmamışsa kurulmalıdır.

  3. Global paketlere yerel bağlantılar otomatik olarak oluşturulmalıdır.

Çözüm:

Zaten tüm geliştiriciler ve tüm ürünler tarafından paylaşılan ortak bir geliştirme çerçevemiz var, bu yüzden gerektiğinde global paketleri yüklemek ve yerel bağlantıları oluşturmak için bir NodeJS betiği oluşturdum. Komut dosyası, ürün temel klasörüne göre ".... \ SharedFiles" dizininde bulunur:

/*******************************************************************************
* $Id: npm-setup.js 12785 2016-01-29 16:34:49Z sthames $
* ==============================================================================
* Parameters: 'links' - Create links in local environment, optional.
* 
* <p>NodeJS script to install common development environment packages in global
* environment. <c>packages</c> object contains list of packages to install.</p>
* 
* <p>Including 'links' creates links in local environment to global packages.</p>
* 
* <p><b>npm ls -g --json</b> command is run to provide the current list of 
* global packages for comparison to required packages. Packages are installed 
* only if not installed. If the package is installed but is not the required 
* package version, the existing package is removed and the required package is 
* installed.</p>.
*
* <p>When provided as a "preinstall" script in a "package.json" file, the "npm
* install" command calls this to verify global dependencies are installed.</p>
*******************************************************************************/
var exec = require('child_process').exec;
var fs   = require('fs');
var path = require('path');

/*---------------------------------------------------------------*/
/* List of packages to install and 'from' value to pass to 'npm  */
/* install'. Value must match the 'from' field in 'npm ls -json' */
/* so this script will recognize a package is already installed. */
/*---------------------------------------------------------------*/
var packages = 
  {
  "bower"                      :                      "bower@1.7.2", 
  "event-stream"               :               "event-stream@3.3.2",
  "gulp"                       :                       "gulp@3.9.0",
  "gulp-angular-templatecache" : "gulp-angular-templatecache@1.8.0",
  "gulp-clean"                 :                 "gulp-clean@0.3.1", 
  "gulp-concat"                :                "gulp-concat@2.6.0",
  "gulp-debug"                 :                 "gulp-debug@2.1.2",
  "gulp-filter"                :                "gulp-filter@3.0.1",
  "gulp-grep-contents"         :         "gulp-grep-contents@0.0.1",
  "gulp-if"                    :                    "gulp-if@2.0.0", 
  "gulp-inject"                :                "gulp-inject@3.0.0", 
  "gulp-minify-css"            :            "gulp-minify-css@1.2.3",
  "gulp-minify-html"           :           "gulp-minify-html@1.0.5",
  "gulp-minify-inline"         :         "gulp-minify-inline@0.1.1",
  "gulp-ng-annotate"           :           "gulp-ng-annotate@1.1.0",
  "gulp-processhtml"           :           "gulp-processhtml@1.1.0",
  "gulp-rev"                   :                   "gulp-rev@6.0.1",
  "gulp-rev-replace"           :           "gulp-rev-replace@0.4.3",
  "gulp-uglify"                :                "gulp-uglify@1.5.1",
  "gulp-useref"                :                "gulp-useref@3.0.4",
  "gulp-util"                  :                  "gulp-util@3.0.7",
  "lazypipe"                   :                   "lazypipe@1.0.1",
  "q"                          :                          "q@1.4.1",
  "through2"                   :                   "through2@2.0.0",

  /*---------------------------------------------------------------*/
  /* fork of 0.2.14 allows passing parameters to main-bower-files. */
  /*---------------------------------------------------------------*/
  "bower-main"                 : "git+https://github.com/Pyo25/bower-main.git" 
  }

/*******************************************************************************
* run */
/**
* Executes <c>cmd</c> in the shell and calls <c>cb</c> on success. Error aborts.
* 
* Note: Error code -4082 is EBUSY error which is sometimes thrown by npm for 
* reasons unknown. Possibly this is due to antivirus program scanning the file 
* but it sometimes happens in cases where an antivirus program does not explain 
* it. The error generally will not happen a second time so this method will call 
* itself to try the command again if the EBUSY error occurs.
* 
* @param  cmd  Command to execute.
* @param  cb   Method to call on success. Text returned from stdout is input.
*******************************************************************************/
var run = function(cmd, cb)
  {
  /*---------------------------------------------*/
  /* Increase the maxBuffer to 10MB for commands */
  /* with a lot of output. This is not necessary */
  /* with spawn but it has other issues.         */
  /*---------------------------------------------*/
  exec(cmd, { maxBuffer: 1000*1024 }, function(err, stdout)
    {
    if      (!err)                   cb(stdout);
    else if (err.code | 0 == -4082) run(cmd, cb);
    else throw err;
    });
  };

/*******************************************************************************
* runCommand */
/**
* Logs the command and calls <c>run</c>.
*******************************************************************************/
var runCommand = function(cmd, cb)
  {
  console.log(cmd);
  run(cmd, cb);
  }

/*******************************************************************************
* Main line
*******************************************************************************/
var doLinks  = (process.argv[2] || "").toLowerCase() == 'links';
var names    = Object.keys(packages);
var name;
var installed;
var links;

/*------------------------------------------*/
/* Get the list of installed packages for   */
/* version comparison and install packages. */
/*------------------------------------------*/
console.log('Configuring global Node environment...')
run('npm ls -g --json', function(stdout)
  {
  installed = JSON.parse(stdout).dependencies || {};
  doWhile();
  });

/*--------------------------------------------*/
/* Start of asynchronous package installation */
/* loop. Do until all packages installed.     */
/*--------------------------------------------*/
var doWhile = function()
  {
  if (name = names.shift())
    doWhile0();
  }

var doWhile0 = function()
  {
  /*----------------------------------------------*/
  /* Installed package specification comes from   */
  /* 'from' field of installed packages. Required */
  /* specification comes from the packages list.  */
  /*----------------------------------------------*/
  var current  = (installed[name] || {}).from;
  var required =   packages[name];

  /*---------------------------------------*/
  /* Install the package if not installed. */
  /*---------------------------------------*/
  if (!current)
    runCommand('npm install -g '+required, doWhile1);

  /*------------------------------------*/
  /* If the installed version does not  */
  /* match, uninstall and then install. */
  /*------------------------------------*/
  else if (current != required)
    {
    delete installed[name];
    runCommand('npm remove -g '+name, function() 
      {
      runCommand('npm remove '+name, doWhile0);
      });
    }

  /*------------------------------------*/
  /* Skip package if already installed. */
  /*------------------------------------*/
  else
    doWhile1();
  };

var doWhile1 = function()
  {
  /*-------------------------------------------------------*/
  /* Create link to global package from local environment. */
  /*-------------------------------------------------------*/
  if (doLinks && !fs.existsSync(path.join('node_modules', name)))
    runCommand('npm link '+name, doWhile);
  else
    doWhile();
  };

Şimdi geliştiricilerimiz için global bir aracı güncellemek istersem, "paket" nesnesini günceller ve yeni komut dosyasını kontrol ederim. Geliştiricilerim bunu kontrol et ve ya global ortamı güncellemek için geliştirilmekte olan ürünlerden "npm-setup.js" ile ya da "npm install" ile çalıştır. Her şey 5 dakika sürer.

Ayrıca, yeni bir geliştiricinin ortamını yapılandırmak için, önce yalnızca Windows için NodeJS ve GIT'i yüklemeli, bilgisayarlarını yeniden başlatmalı, "Paylaşılan Dosyalar" klasörünü ve geliştirilmekte olan ürünleri kontrol etmeli ve çalışmaya başlamalıdırlar.

.NET ürünü için "package.json" yüklemeden önce bu komut dosyasını çağırır:

{ 
"name"                    : "Books",
"description"             : "Node (npm) configuration for Books Database Web Application Tools",
"version"                 : "2.1.1",
"private"                 : true,
"scripts":
  {
  "preinstall"            : "node ../../SharedFiles/npm-setup.js links",
  "postinstall"           : "bower install"
  },
"dependencies": {}
}

notlar

  • Komut dosyası başvurusunun Windows ortamında bile eğik çizgi gerektirdiğini unutmayın.

  • "npm ls" yerel olarak bağlı olan tüm paketler için "package.json" "bağımlılıklarında" listelenmediği için "npm ERR! extraneous:" mesajları verecektir.

Düzenle 1/29/16

Yukarıdaki güncellenmiş npm-setup.jskomut dosyası aşağıdaki gibi değiştirilmiştir:

  • İçindeki "version" var packagespaketi artık npm installkomut satırına iletilen "package" değeridir . Bu, kayıtlı depodan başka bir yerden paketlerin yüklenmesine izin verecek şekilde değiştirildi.

  • Paket zaten yüklüyse ancak istenen paket değilse, varolan paket kaldırılır ve doğru paket yüklenir.

  • Bilinmeyen nedenlerden dolayı, npm, bir yükleme veya bağlantı gerçekleştirirken periyodik olarak bir EBUSY hatası (-4082) atar. Bu hata yakalanır ve komut yeniden yürütülür. Hata nadiren ikinci kez olur ve her zaman temizlenir.


Bu bir cankurtaran @ sthames42! Tam olarak nasıl yapılacağını anlamaya çalışarak saatlerdir trol ediyorum. Açık, kapsamlı, genellikle harika. #points Sorular: (a) Bower neden paketler listesindeyken postinstall'da? (b) Global paketleri yerel olarak BAĞLAMAMAK? Komuta "bağlantılar" eklemeyin?
MaxRocket

@MaxRocket: Yardımcı olabildiğime sevindim. Cevabı en son çalışmamı içerecek şekilde güncelledim. Yanıtlar: (a) burada gösterilmeyen bower.json dosyasında listelenen Bower bileşenlerini yüklemek için 'npm install' yapıldıktan sonra 'bower install' komutu çalışır. İnsanlarımın 'npm install' yazmasını ve başka bir komut yazmak zorunda kalmadan ortamlarını tam olarak kurmasını istedim. (b) Evet.
sthames42

Bu betiğin geçerli sürümü artık burada korunmaktadır .
sthames42

6

Bunun npm_globals.txtyerine , ayrı bir dosya kullanabilirsiniz package.json. Bu dosya, her modülü böyle yeni bir satırda içerecektir,

mongoose@1.4.0
node.io@0.3.3
jquery@1.5.1
jsdom@0.2.0
cron@0.1.2

Sonra komut satırında çalıştırın,

< npm_globals.txt xargs npm install -g

,

npm list -g --depth=0

Eğer ister gelince gereken Bunu yapmak ya da olmasın, tüm kullanım durumuna bağlı olduğunu düşünüyorum. Çoğu proje için bu gerekli değildir; ve projenizin package.jsonbu araçları ve bağımlılıkları birlikte kapsül haline getirmesi çok tercih edilir.

Ama bugünlerde create-react-appyeni bir makineye atladığımda her zaman kuruyorum ve diğer CLI'ları küresel olarak görüyorum. Global bir araç kurmanın kolay bir yoluna sahip olmak güzel ve sürüm oluşturmada bağımlılıkları çok önemli değil.

Ve günümüzde, paketleri global olarak kurmak yerine npx, bir npm paket çalıştırıcısı kullanıyorum .


3

Package.json içindeki tüm modüller ./node_modules/ dizinine kurulur

Bu açıkça belirtilen bulamadı ama bu NPM için package.json referans .


1

Global bağımlılıkları yüklemek için kendi komut dosyanızı oluşturun. Fazla sürmez. package.json oldukça genişletilebilir.

const {execSync} = require('child_process');

JSON.parse(fs.readFileSync('package.json'))
     .globalDependencies.foreach(
         globaldep => execSync('npm i -g ' + globaldep)
     );

Yukarıdakileri kullanarak, hatta satır içi yapabilirsiniz!

Aşağıdaki ön yüklemeye bakın:

{
  "name": "Project Name",
  "version": "0.1.0",
  "description": "Project Description",
  "main": "app.js",
  "scripts": {
    "preinstall": "node -e \"const {execSync} = require('child_process'); JSON.parse(fs.readFileSync('package.json')).globalDependencies.foreach(globaldep => execSync('npm i -g ' + globaldep));\"",
    "build": "your transpile/compile script",
    "start": "node app.js",
    "test": "./node_modules/.bin/mocha --reporter spec",
    "patch-release": "npm version patch && npm publish && git add . && git commit -m \"auto-commit\" && git push --follow-tags"
  },
  "dependencies": [
  },
  "globalDependencies": [
    "cordova@8.1.2",
    "ionic",
    "potato"
  ],
  "author": "author",
  "license": "MIT",
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^5.2.0"
  },
  "bin": {
    "app": "app.js"
  }
}

Düğüm yazarları package.json'un bir proje dosyası olduğunu kabul etmeyebilir. Ama bu.

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.