Bieganie sudo npm install -g wydaje się dość powszechną radą w Internecie. mean.io, wiodący generator/biblioteka frameworków internetowych, sugeruje nawet zrobienie tego na własnej stronie głównej.

Używanie sudo npm install (i potencjalnie sudo npm <anything>) to zły pomysł ™. Jest to problem z co najmniej kilku powodów:

  • npm install ma możliwość uruchamiania dowolnych skryptów. Ze względu na sposób skonfigurowania npm oraz fakt, że możesz zmieniać rejestr i korzystać z DNS, możliwe jest, że przypadkowo zainstalujesz złośliwy pakiet w ogóle, zainstalujesz złośliwy pakiet udający całkowicie prawidłowy pakiet lub zainstalujesz pakiet z dobrymi intencjami, który może uruchamiać skrypty, które w jakiś sposób są szkodliwe dla twojego systemu, jeśli zostaną uruchomione jako root.
  • Uruchomienie sudo npm install (bez -g) spowoduje utworzenie katalogu lokalnego, który może zmieniać tylko użytkownik root. To naprawdę może ci wszystko zepsuć, jeśli spróbujesz później zrobić npm <something> w tym samym katalogu lub projekcie.
  • Nawet sudo npm install -g z prawidłowym celem instalacji może popsuć sytuację i w pewnych okolicznościach w przyszłości utrudnić korzystanie z npm bez sudo - szczególnie jeśli zmienisz konfigurację npm w trakcie instalacji. Użytkownik root może i będzie tworzyć pliki w pamięci podręcznej npm i potencjalnie plik taki jak ~/.npm/_locks, a w przyszłości npm install lub npm install -g spowoduje straszny błąd EACCES.

Jeśli więc chodzi o używanie sudo z npm: po prostu tego nie rób.

npm install -g dla siebie

Przez większość czasu prawdopodobnie będziesz pracować w systemie, który wymaga tylko jednego użytkownika do korzystania z węzła i globalnie zainstalowanych plików binarnych (ty na własnej maszynie, kilku node użytkowników na serwerach). Najprostszym rozwiązaniem problemu npm install -g jest po prostu zmiana miejsca instalacji modułów węzła.

Wyraźny przedrostek

npm używa ustawienia prefix do określenia, gdzie ma zostać zainstalowana globalnie — lub przynajmniej co wywołuje globalnie. Możesz zobaczyć, jaki jest ustawiony prefiks, uruchamiając npm prefix -g i prawdopodobnie jest to coś w rodzaju /usr. Jest to niepożądane. Zamiast tego byłoby miło globalnie zainstalować moduły węzłów w katalogu, do którego ma dostęp bieżący użytkownik.

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

Oczywiście możesz zmienić prefiks na dowolny. Konieczność wpisywania tej opcji --prefix za każdym razem byłaby również ogromnie uciążliwa, więc na szczęście istnieje plik .npmrc, którego npm użyje do sprawdzenia ustawień domyślnych. Mój wygląda tak:

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

Oczywiście możesz wybrać dowolne wartości. Pełna lista wszystkich ustawień konfiguracyjnych, które możesz zastosować do polecenia npm lub ustawić w swoim .npmrc, znajduje się na liście npm help 7 config (znalezienie tego wymagało trochę kopania).

W każdym razie, gdy wybierzesz jakieś ładne, ukryte foldery, npm install -g przestanie umieszczać wszelkiego rodzaju śmieci w twoim katalogu domowym, katalogu /usr i różnych innych miejscach, gdy uruchomisz npm install -g (i npm install w niektórych przypadkach ).

Niestety, wydaje się, że nie ma ustawienia konfiguracyjnego umożliwiającego umieszczenie npm-debug.log ... jeszcze.

Podsumowując, ustawienie prefix w .npmrc lub po prostu użycie --prefix pozwoli ci używać npm install -g bez sudo.

Ale czekaj! Musisz także upewnić się, że pliki binarne są na Twojej ścieżce. Po prostu dodaj $PREFIX/bin do swojej ścieżki. Zatem w moim przypadku:

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

Zauważ, że ustawienie NODE_PATH spowoduje, że node sprawdzi tę ścieżkę w poszukiwaniu bibliotek. „Więcej informacji znajdziesz tutaj”, co może, ale nie musi, być pożądane. Dołączyłem to tylko dla kompletności.

Korzystanie z nvm

Konfigurowanie .npmrc i $PATH może wymagać dużo pracy. No cóż, niezupełnie, ale wyobraź sobie, że tak jest.

Pamiętaj też, że Twoja aktualna wersja npm/node ma znaczenie. Niektóre biblioteki mogą obsługiwać lub wymuszać jedynie wymagania wersji 0.10, podczas gdy w systemie może być uruchomiona wersja 0.12.

nvm to niesamowity pakiet, który wymaga bardzo niewielkiej konfiguracji i pozwala na łatwą instalację i przełączanie pomiędzy wersjami węzłów. Możesz nawet dodać nvm use <specific-version> do swojego profilu, jeśli dużo pracujesz z konkretną wersją i chcesz jej używać za każdym razem, gdy uruchamiasz powłokę.

Dlaczego więc to jest świetne? nvm aktualizuje Twój prefiks! — przynajmniej jeśli jeszcze go nie ustawiłeś. Zainstaluje pliki binarne w ~/.nvm/<version>/bin. Dodaje ten katalog do twojego $PATH, kiedy uruchomisz nvm use! A jeśli wrócisz do nvm use system lub innej wersji, zostanie ona odpowiednio usunięta.

Pamiętaj więc, że pliki binarne zainstalowane po nvm use będą przydatne tylko wtedy, gdy zrobisz to samo nvm use ponownie (chyba że zaktualizujesz ścieżkę, aby uwzględnić je jawnie).

Pamiętaj, że nvm robi to tylko, jeśli nie masz ustawionego prefix w swoim .npmrc. Oczywiście nadal możesz zastąpić wszystko za pomocą npm --prefix. Jeśli masz prefix w swoim .npmrc lub używasz --prefix, wówczas npm install -g użyte po nvm use nadal będzie korzystać z ustawień przedrostka. Myślę, że to zazwyczaj dobra rzecz.

Wystąpiły drobne problemy związane z nieprawidłowym pozyskiwaniem nvm. Wystarczy, że zrobisz source /path/to/nvm/nvm.sh. nvm próbuje automatycznie dodać to do Twojego profilu, ale nie zawsze działa zgodnie z oczekiwaniami. Aktualizuj .zshrc, .bashrc, inne w razie potrzeby.

npm install -g dla serwera

Poprzednia sekcja doskonale ma zastosowanie w przypadku serwera, na którym wdrażasz aplikację węzła. Zwykle twój serwer będzie miał użytkownika (nazwij go node lub jak chcesz), który jest odpowiedzialny za uruchomienie węzła. Skonfiguruj ich .npmrc lub po prostu skonfiguruj zadania kompilacji, aby używać --prefix w razie potrzeby.

To nadal nie jest przypadek użycia dla sudo npm install.

npm install -g dla wszystkich użytkowników

Może się zdarzyć, że system umożliwi wielu użytkownikom globalną instalację i używanie plików binarnych i bibliotek pakietów węzłów. Nadal nie ma powodu, aby używać do tego sudo — przynajmniej nie w przypadku polecenia npm.

Moje rozwiązanie polegałoby na utworzeniu katalogu, w którym można zainstalować globalne moduły węzła — być może w /var, chociaż /usr mogłoby być prawidłowe... Jednak nadal jestem tego ostrożny, ponieważ w /usr/bin są rzeczy niebędące węzłami.

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

!$ powyżej to rozwinięcie historii dla „ostatniego słowa poprzedniego polecenia” lub /usr/{bin,lib/node_modules} w obu przypadkach.

Spowoduje to utworzenie grupy, która może uruchomić npm install -g i dodać moduły węzłów do /usr/lib. Możesz dodać zaufanych użytkowników do tej grupy w swoim systemie i przeprowadzić prawdziwą globalną instalację modułów węzła.

Jednakże głównym zastrzeżeniem tego rozwiązania jest to, że każdy w npm-global-installers może zablokować globalne instalacje innych osób. Osoby fizyczne mogą rozwiązać ten problem po prostu używając własnego przedrostka, ale jest to sprzeczne z celem instalacji globalnej.

Innym rozwiązaniem jest po prostu posiadanie npm-global-intaller użytkownika i zaktualizowanie jego prefix do ~/npm, a następnie poproszenie wszystkich o dodanie ~npm-global-installer/npm do swoich $PATH. Inni użytkownicy mogą wykonywać te instalacje globalne przy użyciu sudo z użytkownikiem npm-global-installer (nie root — nie testowałem tego i nadal może to spowodować utworzenie ~/.npm/_locks, do których nie masz uprawnień) lub tego katalogu można zapisać w grupie/świecie.

Obydwa powyższe rozwiązania umożliwiają wielu użytkownikom korzystanie z plików binarnych/bibliotek pakietów węzłów w całym systemie.

Oczywiście, jeśli naprawdę chcesz korzystać z bibliotek zainstalowanych przez innego użytkownika, możesz zaktualizować swój $NODE_PATH, aby je uwzględnić. Jeśli chcesz użyć pliku binarnego, zaktualizuj swój $PATH, aby go uwzględnić, lub nawet po prostu wykonaj /home/other-user/path/to/node/bin/script (zakładając, że możesz go uruchomić).

Uruchomiłem już sudo npm install. Pomoc!

Jeśli napotykasz dziwne błędy przy npm install - szczególnie te, które mówią EACCES dużo po tym, jak zrobiłeś sudo npm install w przeszłości, najprawdopodobniej jest to problem z uprawnieniami do katalogów, które npm próbuje zmienić. Jest to konsekwencja npm bycia głupim w dobrym tego słowa znaczeniu. Z radością spróbuje zrobić to, co mu każesz i utworzy pliki i katalogi z uprawnieniami roota lub spróbuje je zmienić, jeśli nie masz takich uprawnień.

Mając to na uwadze, kiedy zajdzie potrzeba modyfikacji pliku utworzonego przez sudo npm install, musisz użyć uprawnień, aby zmienić jego uprawnienia lub całkowicie go usunąć.

Najprostszym rozwiązaniem jest wykonanie sudo rm -rf node_modules dla dowolnego projektu, w którym aktualnie się znajdujesz. Podobnie, być może będziesz musiał zrobić coś podobnego do sudo rm -rf $(npm prefix -g)/{bin,lib/node_modules} w przypadku globalnej instalacji modułów węzłów z niewłaściwym przedrostkiem. Pamiętaj tylko, że to spowoduje usunięcie bibliotek, które zainstalowałeś wcześniej z sudo, więc będziesz musiał je zainstalować ponownie. Właściwy sposób. Potraktuj to jako swoją zdobycz.

Dokładniej zwróć uwagę na wynik. Przeczytaj, co mówi npm i znajdź katalog, który konkretnie powoduje problem. Usunąć to. Jeśli nie możesz go usunąć, będziesz musiał użyć sudo rm.

Ostatecznie powinieneś być w stanie wykonać npm install lub npm install -g bez użycia sudo.

Czasami jednak możesz napotkać inne, niezwiązane ze sobą problemy (spróbuj npm install oracledb!).

Wiedz, co robisz z sudo

Mam wrażenie, że wielu programistów wyciągnęło z tego lekcję

Jeśli coś nie zadziała, spróbuj ponownie, używając sudo.

Przypomina mi to podobną sytuację: jeśli kill nie zabije procesu, użyj kill -9. Myślę, że możesz zapytać wielu programistów, jakie sygnały kill i kill -9 wysyłają do procesów, a wielu z nich odpowiedziałoby pustym spojrzeniem (SIGTERM ORAZ SIGKILL).

W tym samym duchu użycie sudo nie jest odpowiedzią na wszystko. Nie bez powodu root nazywany jest użytkownikiem uprzywilejowanym. Zdobywasz przywileje, pełniąc odpowiedzialność, a najważniejszym z tych obowiązków jest wiedza, co zrobi polecenie, gdy faktycznie je wykonasz.

Jeśli nie wiesz dokładnie, co zrobi polecenie przed uruchomieniem go z sudo (lub nie zależy ci na zepsuciu systemu, w którym się znajdujesz), zapytaj kogoś. sudo to coś, czego należy używać ostrożnie, a nie sfrustrowanego porzucenia. A jeśli o to chodzi, wiedz, że visudo i sudoedit też istnieją!

Jeśli jednak chcesz coś wynieść z tego postu, powinno to być to, że nigdy nie musisz robić sudo npm niczego.

Nawiasem mówiąc, wymawia się to „sue doo”.

Oryginalnie opublikowano na blog.explosion-pills.com 9 kwietnia 2015 r.