Requesting `npm` alias for `node` package

We’re shipping 3 executables in the node package: node, npm and yarn. I’d like to get npm lifted to a top-level command via an alias please. We need to do a bit more testing on yarn with the Yarn team before we proceed so I’ll add that as a separate request.

https://github.com/nodesource/distributions/tree/master/snap

2 Likes

+1 for npm since it is very natural for it to be provided by this snap.

We still need one more vote to process. Can another reviewer take a look?

Indeed, that one seems straightforward. +1

+1 from me too. Makes sense.

The voting period is over. 3 votes for, 0 against. Granting the alias. This is now live.

Why does npm from node snap require root to install packages? Won’t that make a lot of problems in using frameworks like angular when building and running the app?

aresminos@desktop:~$ npm install -g typescript
npm WARN checkPermissions Missing write access to /usr/local/lib
npm ERR! path /usr/local/lib
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall access
npm ERR! Error: EACCES: permission denied, access '/usr/local/lib'
npm ERR!  { Error: EACCES: permission denied, access '/usr/local/lib'
npm ERR!   stack: 'Error: EACCES: permission denied, access \'/usr/local/lib\'',
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/local/lib' }
npm ERR! 
npm ERR! Please try running this command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/aresminos/.npm/_logs/2018-05-10T09_30_17_145Z-debug.log

From the logs:

0 info it worked if it ends with ok
1 verbose cli [ '/snap/node/567/bin/node',
1 verbose cli   '/snap/node/567/bin/npm',
1 verbose cli   'install',
1 verbose cli   '-g',
1 verbose cli   'typescript' ]
2 info using npm@5.6.0
3 info using node@v10.1.0
4 verbose npm-session 9f8eaf7bf4fc6a57
5 silly install loadCurrentTree
6 silly install readGlobalPackageData
7 http fetch GET 200 https://registry.npmjs.org/typescript 419ms
8 silly pacote tag manifest for typescript@latest fetched in 470ms
9 silly install loadIdealTree
10 silly install cloneCurrentTreeToIdealTree
11 silly install loadShrinkwrap
12 silly install loadAllDepsIntoIdealTree
13 silly resolveWithNewModule typescript@2.8.3 checking installable status
14 silly currentTree lib
15 silly idealTree lib
15 silly idealTree └── typescript@2.8.3
16 silly install generateActionsToTake
17 warn checkPermissions Missing write access to /usr/local/lib
18 verbose stack Error: EACCES: permission denied, access '/usr/local/lib'
19 verbose cwd /home/aresminos
20 verbose Linux 4.15.0-20-generic
21 verbose argv "/snap/node/567/bin/node" "/snap/node/567/bin/npm" "install" "-g" "typescript"
22 verbose node v10.1.0
23 verbose npm  v5.6.0
24 error path /usr/local/lib
25 error code EACCES
26 error errno -13
27 error syscall access
28 error Error: EACCES: permission denied, access '/usr/local/lib'
28 error  { Error: EACCES: permission denied, access '/usr/local/lib'
28 error   stack: 'Error: EACCES: permission denied, access \'/usr/local/lib\'',
28 error   errno: -13,
28 error   code: 'EACCES',
28 error   syscall: 'access',
28 error   path: '/usr/local/lib' }
29 error Please try running this command again as root/Administrator.
30 verbose exit [ -13, true ]

Here is a solution but shouldn’t something in the snap be changed? This solution is not the default, and afaik npm never asked for root to install global packages. Anyway, follow these links:

https://docs.npmjs.com/getting-started/fixing-npm-permissions

You used -g, which means install it for all users - “globally”.

Obviously but that didn’t required root when using npm from an nvm node installation.

probably someone learned from

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-7408

:wink:

2 Likes

This is a standard problem with Node, not specific to the snap install by the way. It’s not a great idea to use sudo but there are some typical ways of getting around this:

  1. Avoid -g if you can, seriously. Many install instructions will have -g but they don’t really need it. Do you really want to clutter up your global space with things you’re not going to re-use? If you need a command-line utility then maybe npx (https://github.com/zkat/npx) or reaching in to node_modules/.bin/ is enough? Also keep in mind that anything in "scripts" in your package.json has node_modules/.bin/ in its PATH so they don’t need to be globals if you are scripting something up for a node package.
  2. chown $USER -R /usr/local/ - this has become a common pattern on developer (single-user) machines. If you own the machine and you’re the only one on it, then it’s not a bad thing to just take ownership of /usr/local. I do this on my machines and it gives me -g access without sudo, amongst other benefits.
  3. Set your own npm prefix. For the snap, it’s set to /usr/local, but it could also be /home/me/node_global/. Anything you install with -gwill go into$prefix/lib/node_modules/ with executables in $prefix/bin/. Use npm config set prefix /home/me/whatever to change it, just put that path + /bin/ into your PATH and you have what you need.

There’s not much for the snap to do here, it’s not going to set up a per-user $prefix since the standard behaviour is for -g to be for global executable scripts. It would also be wrong for it to escalate privileges without asking you, so an opt-in sudo is appropriate here if it’s going to be installing things outside of a space that you as a user have access to.