Problemas de permisos con NPM

En algunos casos, sobre todo cuando instalamos paquetes de forma global con NPM, puede que tengamos problemas de permisos. Esto ocurre porque por defecto, los paquetes globales se instalan en /usr y muchas veces el usuario no tiene los permisos adecuados.

Error: EACCES: permission denied

La razón más frecuente de este tipo de problemas es porque se ha utilizado npm como root (o se ha realizado un sudo npm) y al intentar instalar un paquete nos aparece un mensaje parecido al siguiente, donde se observan errores de permiso denegado:

[...]
npm WARN checkPermissions Missing write access to /usr/lib/node_modules/less
npm WARN checkPermissions Missing write access to /usr/lib/node_modules/less/node_modules
npm WARN checkPermissions Missing write access to /usr/lib/node_modules
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/lib/node_modules/less/node_modules/asap
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/usr/lib/node_modules/less/node_modules/asap'
npm ERR!  [Error: EACCES: permission denied, access '/usr/lib/node_modules/less/node_modules/asap'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/lib/node_modules/less/node_modules/asap'
npm ERR! }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/manz/.npm/_logs/2020-08-05T11_22_20_260Z-debug.log

NUNCA utilices sudo con npm (ni lo ejecutes como root). De lo contrario, es muy probable que termines teniendo estos problemas de permisos.

Si probamos a ejecutar el comando npm config get prefix, se nos mostrará la carpeta donde se instalan los paquetes globales:

$ npm config get prefix
/usr

Por ejemplo, en este caso, los ejecutables de línea de comandos se instalarán en /usr/bin, los paquetes en /usr/lib/node_modules, etc...

Comprobación de problemas

Antes de continuar, podemos utilizar el comando npm doctor para comprobar el estado de nuestra instalación de npm y verificar si hay algún problema en ella. Para ello, simplemente escribimos en una terminal npm doctor:

$ npm doctor

npm notice PING https://registry.npmjs.org/
Check                               Value                        Recommendation
npm ping                            ok
npm -v                              v6.14.7
node -v                             v14.7.0
npm config get registry             https://registry.npmjs.org/
which git                           not installed                Install git and ensure it's in your PATH.
Perms check on cached files         notOk                        Check the permissions of your files in /root/.npm
Perms check on global node_modules  notOk                        /usr/lib/node_modules must be readable and writable by the current user.
Perms check on local node_modules   notOk                        /node_modules must be readable and writable by the current user.
Verify cache contents               notOk

Este comando realizará una serie de comprobaciones y nos mostrará en rojo si encuentra problemas.

En el ejemplo anterior, observa que todo va correctamente hasta llegar a las últimas 5 líneas, donde nos dice que no tenemos git instalado (se requiere tener instalado) y nos muestra un notOk en el apartado de permisos porque se han realizado instalaciones con sudo npm, por lo que tenemos la certeza de que tenemos una instalación de node defectuosa.

Solucionar problema de permisos

Una forma segura de solucionar estos problemas, es cambiar la ruta que usamos por defecto /usr e indicar una nueva ruta que se encuentre dentro de las carpetas de nuestro usuario. De esta forma no tendremos problemas de permisos ya que cada usuario tendrá su propia configuración de NPM.

Vamos a cambiar la carpeta /usr a la carpeta /home/user/.npm-global:

# Creamos la mencionada carpeta
$ mkdir ~/.npm-global

# La establecemos como prefijo de NPM
$ npm config set prefix '~/.npm-global'

Sin embargo, ten en cuenta que aunque hemos cambiado el prefijo, aún tenemos que añadir al PATH del sistema la carpeta de ejecutables de node, ya que de lo contrario, no encontrará los comandos que instalemos.

Para ello, simplemente tenemos que añadir la siguiente línea a nuestro archivo de arranque de terminal, dependiendo de su usamos bash o si usamos zsh, por ejemplo:

# En el ~/.bashrc
export PATH=~/.npm-global/bin:$PATH

# En el ~/.zshrc
export NPM_CONFIG_PREFIX=~/.npm-global/bin

Con esto, al reiniciar la terminal, estaremos listos para utilizar npm sin problemas de permisos. Podemos volver a ejecutar npm doctor para comprobar si todo funciona correctamente, en cuyo caso debería aparecernos algo así:

$ npm doctor

npm notice PING https://registry.npmjs.org/
Check                               Value                        Recommendation
npm ping                            ok
npm -v                              v6.14.7
node -v                             v14.6.0
npm config get registry             https://registry.npmjs.org/
which git                           /usr/bin/git
Perms check on cached files         ok
Perms check on global node_modules  ok
Perms check on local node_modules   ok
Verify cache contents               verified 8670 tarballs

Ten en cuenta que pasaremos a no tener instalado ningún paquete de forma global, ya que hemos cambiado a una nueva ruta vacía.

Manz
Publicado por Manz

Docente, divulgador informático y freelance. Autor de Emezeta.com, es profesor en la Universidad de La Laguna y dirige el curso de Programación web FullStack y Diseño web FrontEnd de EOI en Tenerife (Canarias). En sus ratos libres, busca GIF de gatos en Internet.