Alergarea sudo npm install -g pare a fi un sfat destul de comun pe Internet. mean.io, un generator/bibliotecă de compilare a cadrului web proeminent sugerează chiar să o facă pe propria lor pagină de pornire.

Utilizarea sudo npm install (și potențial sudo npm <anything>) este o idee proastă™. Aceasta este o problemă din cel puțin câteva motive:

  • npm install are capacitatea de a rula scripturi arbitrare. Datorită modului în care este configurat npm și a faptului că puteți modifica registry și poate utiliza DNS, este posibil să instalați accidental un pachet rău intenționat în general, să instalați un pachet rău intenționat pretins ca un pachet perfect valid sau să instalați un pachet cu bune intenții care pot rula scripturi care sunt cumva dăunătoare sistemului dvs. dacă sunt executate ca root.
  • Rularea sudo npm install (fără -g) va crea un director local care poate fi modificat numai de utilizatorul root. Acest lucru vă poate strica lucrurile dacă mai târziu încercați să faceți npm <something> în același director sau proiect.
  • Chiar și sudo npm install -g cu o țintă de instalare validă vă poate încurca lucrurile și vă poate îngreuna folosirea npm fără sudo în anumite circumstanțe în viitor -- mai ales dacă vă schimbați configurația npm midstream. Utilizatorul root poate și va crea fișiere în memoria cache npm și, eventual, un fișier precum ~/.npm/_locks, iar viitoarele npm install sau npm install -g vă vor da temuta eroare EACCES.

Deci, când vine vorba de utilizarea sudo cu npm: nu o faceți.

npm install -g pentru tine

De cele mai multe ori, probabil că veți lucra la un sistem care necesită doar un singur utilizator să folosească nodul și binarele instalate la nivel global (dvs. pe propria mașină, un utilizator node pe servere). Cea mai simplă soluție pentru problema npm install -g este să schimbați pur și simplu locul unde sunt instalate modulele nodului.

Prefix explicit

npm folosește setarea prefix pentru a determina unde să se instaleze la nivel global -- sau cel puțin ce numește la nivel global. Puteți vedea la ce este setat prefixul rulând npm prefix -g și probabil este ceva de genul /usr. Acest lucru este de nedorit. În schimb, ar fi bine să instalați module de noduri la nivel global într-un director la care are acces utilizatorul curent.

npm --prefix=/home/your-user/.global-node-modules install -g grunt-cli

Desigur, puteți schimba prefixul cu orice doriți. De asemenea, ar fi o durere enormă să trebuiască să tastați această opțiune --prefix de fiecare dată, așa că, din fericire, există un fișier .npmrc pe care npm îl va folosi pentru a verifica valorile implicite. Al meu arata asa:

# ~/.npmrc tmp=/home/ajcrites/files/node-tmp cache=/home/ajcrites/.npmcache prefix=/home/ajcrites/.npm

Desigur, puteți alege orice valoare doriți. O listă completă a tuturor setărilor de configurare pe care le puteți aplica la comanda npm sau le puteți seta în .npmrc este listată cu npm help 7 config (a fost nevoie de câteva săpături pentru a găsi).

În orice caz, odată ce ai ales niște foldere ascunse și frumoase, npm install -g nu va mai pune tot felul de gunoi în directorul tău de acasă, în directorul /usr și în diverse alte locuri atunci când rulezi npm install -g (și npm install în unele cazuri ).

Din păcate, nu pare să existe o setare de configurare pentru unde să puneți npm-debug.log ... încă.

În rezumat, setarea prefix în .npmrc sau pur și simplu folosirea --prefix vă va permite să utilizați npm install -g fără sudo.

Dar așteptați! De asemenea, trebuie să vă asigurați că binarele sunt pe calea dvs. Pur și simplu adăugați $PREFIX/bin la calea dvs. Deci in cazul meu:

# .zshrc / .bashrc / .profile / etc. export PATH=$PATH:$HOME/.npm/bin export NODE_PATH=$NODE_PATH:$HOME/.npm/lib/node_modules

Rețineți că setarea lui NODE_PATH va face ca node să verifice această cale pentru biblioteci. „Mai multe informații sunt aici”, iar acest lucru poate sau nu este întotdeauna de dorit. L-am inclus doar pentru a fi complet.

Folosind nvm

Configurarea .npmrc și $PATH poate fi multă muncă. Ei bine, nu chiar, dar imaginați-vă că este.

De asemenea, rețineți că versiunea dvs. actuală de npm/node contează. Este posibil ca unele biblioteci să accepte sau să impună doar o cerință a v0.10, în timp ce este posibil să rulați v0.12 pe sistemul dumneavoastră.

nvm este un pachet minunat care necesită foarte puțină configurare și vă permite să instalați și să comutați cu ușurință între versiunile de noduri. Puteți chiar să adăugați nvm use <specific-version> la profilul dvs. dacă lucrați mult cu o anumită versiune și doriți să o utilizați de fiecare dată când începeți un shell.

Deci de ce este grozav? nvm vă actualizează prefixul! -- cel puțin dacă nu ați setat deja unul. Va instala binare la ~/.nvm/<version>/bin. Acesta adaugă acest director la $PATH atunci când rulați și nvm use! Și dacă revii la nvm use system sau la o altă versiune, o elimină în mod corespunzător.

Așadar, rețineți că binarele instalate după nvm use vor fi utilizabile numai atunci când faceți din nou același nvm use (cu excepția cazului în care vă actualizați calea pentru a le include în mod explicit).

Rețineți că nvm face acest lucru numai dacă nu aveți prefix setat în .npmrc. Bineînțeles, puteți încă să suprascrieți totul cu npm --prefix. Dacă aveți prefix în .npmrc sau folosiți --prefix, atunci npm install -g folosit după nvm use va folosi în continuare setările prefixului. Cred că acesta este de obicei un lucru bun.

Am întâmpinat mici probleme cu nvm care nu este furnizat corect. Trebuie doar să faci source /path/to/nvm/nvm.sh. nvm încearcă să adauge automat acest lucru la profilul tău, dar s-ar putea să nu funcționeze întotdeauna conform așteptărilor. Actualizați .zshrc, .bashrc, altele după cum este necesar.

npm install -g pentru un server

Secțiunea anterioară este perfect aplicabilă pentru un server în care implementați o aplicație nod. De obicei, serverul dvs. va avea un utilizator (numiți-l node sau cum doriți) care este responsabil de rularea nodului. Configurați-le .npmrc sau doar configurați-vă lucrările de construcție pentru a utiliza --prefix după caz.

Acesta nu este încă un caz de utilizare pentru sudo npm install.

npm install -g pentru toți utilizatorii

Poate exista ocazie ca un sistem să permită mai multor utilizatori să instaleze și să utilizeze la nivel global pachetele binare și biblioteci de noduri. Nu există încă niciun motiv să folosiți sudo pentru a face asta -- cel puțin nu pentru comanda npm.

Soluția mea pentru aceasta ar implica crearea unui director pentru a instala modulele globale de noduri — poate în /var, deși /usr ar putea fi valid... Mă tem în continuare de acest lucru, deși, deoarece există lucruri non-noduri în /usr/bin.

sudo addgroup npm-global-installers sudo mkdir -p /usr/{bin,lib/node_modules} sudo chgrp -R npm-global-installers !$ sudo chmod -R g+w !$

!$ de mai sus este extinderea istoricului pentru „ultimul cuvânt al comenzii anterioare” sau /usr/{bin,lib/node_modules} în ambele cazuri.

Acest lucru creează un grup care poate rula npm install -g pentru a adăuga module de noduri la /usr/lib. Puteți adăuga utilizatori de încredere la acest grup pe sistemul dvs. și puteți face o instalare globală adevărată a modulelor nod.

Cu toate acestea, o avertizare majoră la această soluție este că oricine din npm-global-installers poate bloca instalările globale ale altora. Persoanele fizice pot rezolva această problemă pur și simplu folosind propriul prefix, dar acest lucru înfrânge scopul instalării globale.

O altă soluție este pur și simplu să ai un utilizator npm-global-intaller și să-i actualizezi prefix la ~/npm -- apoi să adauge pe toți ~npm-global-installer/npm la $PATH. Alți utilizatori pot face aceste instalări globale folosind sudo cu utilizatorul npm-global-installer (nu rădăcină -- nu am testat acest lucru și încă s-ar putea să facă ceva ~/.npm/_locks pentru care nu aveți permisiuni) sau acest director poate fi făcut inscriptibil în grup/lume.

Ambele soluții de mai sus sunt viabile pentru a permite mai multor utilizatori să utilizeze pachetele binare / biblioteci de noduri la nivelul întregului sistem.

Desigur, dacă doriți cu adevărat să utilizați bibliotecile instalate de alt utilizator, puteți actualiza $NODE_PATH pentru a-l include. Dacă doriți să utilizați un binar, actualizați $PATH pentru a-l include sau chiar faceți /home/other-user/path/to/node/bin/script (presupunând că îl puteți executa).

Am rulat deja sudo npm install. Ajutor!

Dacă întâmpinați erori ciudate cu npm install -- în special lucruri care spun EACCES mult după ce ați făcut sudo npm install în trecut, cel mai probabil este o problemă de permisiuni pentru directoarele pe care npm încearcă să le modifice. Aceasta este o consecință a npm a fi prost în sensul bun. Va încerca bucuros să facă ceea ce îi spuneți să facă și să creeze fișiere și directoare care au permisiuni root sau să încerce să le modifice atunci când nu aveți astfel de permisiuni.

Acestea fiind spuse, dată ce trebuie să modificați un fișier creat de sudo npm install, trebuie să utilizați privilegii fie pentru a-i modifica permisiunile, fie pentru a-l elimina complet.

Cea mai simplă soluție este să faceți sudo rm -rf node_modules pentru orice proiect în care vă aflați în prezent. În mod similar, poate fi necesar să faceți ceva asemănător sudo rm -rf $(npm prefix -g)/{bin,lib/node_modules} în cazul în care ați instalat global module de noduri cu prefixul greșit. Trebuie doar să știți că acest lucru va elimina bibliotecile pe care le-ați instalat cu sudo înainte, așa că va trebui să le instalați din nou. Calea cea buna. Consideră asta ca apariția ta.

Mai precis, acordați atenție rezultatelor. Citiți ce vă spune npm și găsiți directorul care cauzează o problemă în mod specific. Scoateți-l. Dacă nu îl puteți elimina, va trebui să utilizați sudo rm.

În cele din urmă, ar trebui să puteți face un npm install sau npm install -g fără să utilizați sudo.

Uneori, s-ar putea să întâmpinați și alte probleme fără legătură, totuși (încercați npm install oracledb!)

Află ce faci cu sudo

Am ideea că mulți dezvoltatori învață lecția

Dacă ceva nu funcționează, încercați din nou cu sudo.

Acest lucru îmi amintește de o circumstanță similară: dacă kill nu oprește un proces, utilizați kill -9. Cred că ați putea întreba mulți dezvoltatori care semnale kill și kill -9 trimit proceselor și mulți v-ar arunca o privire în gol ca răspuns (SIGTERM ȘI SIGKILL).

În același sens, folosirea sudo nu este un răspuns pentru toate. Există un motiv pentru care root este numit utilizator privilegiat. Câștigi privilegii exercitând responsabilitatea, iar principala dintre aceste responsabilități este să știi ce va face o comandă atunci când o conduci de fapt.

Cu excepția cazului în care știi exact ce va face o comandă înainte de a o rula cu sudo (sau nu îți pasă să strici sistemul pe care te afli) întreaba pe cineva. sudo este ceva care ar trebui folosit cu grijă, nu cu abandon frustrat. De altfel, să știți că și visudo și sudoedit există!

Dacă elimini ceva din această postare, totuși, ar trebui să fie că nu trebuie să faci niciodată sudo npm pentru nimic.

Apropo, se pronunță „sue doo”.

Publicat inițial pe blog.explosion-pills.com pe 9 aprilie 2015.