Making Global NPM packages available to all users on windows 2012 server - node.js

I am trying to install continues integration server. This server will pull data from GIT and it will try to build the application. Since I am using windows 2012 server, multiple users can trigger the build. For this purpose, I want to ensure all the node packages I install as admin are available to all users.
How can I:
Install node packages globally that are available to all users.
I want to use a locally hosted node registry. I don't want to use node registry.
After the installing the packages, how can I validate if all users can access the packages?

Had the same issue. Needed the CI build agent to run a global package on the CLI. Saw this post in a new feature request for system-wide npm -g for Windows.
In short:
Open an administrator level command prompt
Note the current global prefix: npm prefix -g
Set the global prefix to the CI user: npm config set prefix <C:\Users\CI_USER\AppData\Roaming\npm>
Install the needed packages: npm i -g PKG
Restore the prefix to the previous value.

For the 'Network Service' account use the folder:
C:\Windows\ServiceProfiles\NetworkService\AppData\Roaming\npm

You can add a global environment variable NODE_PATH to set the package require search path. You may see here for more.
https://gist.github.com/branneman/8048520#4-the-environment

Related

how to make npm package available for all users

I installed angular-cli on my root user. So when I check ng version it works and gives the angular version.
But when I check this from a non root user I cannot see it. How can I make this available for all users.
os - oracle linux 7
tried npm config prefix /usr/local it does not work
For the 'Network Service' account use the folder:
C:\Windows\ServiceProfiles\NetworkService\AppData\Roaming\npm

Unable to install botskills command

Unable to install npm botskills command on Self-Hosted Azure agent.
Used following command to install packages get updated but when tried to check using "botskills" command it throws up and error saying botskills not available.
Screenshots
Used " npm install -g botskills#latest " to install the package where the following screenshot infers that the botskill packages have been updated.
But when tried to use the updated package it does not work
All the other supporting packages have been updated.
This issue occurs while using the Self-Hosted agent (Windows agent) only and works with no issue on local.
Steps to reproduce
1) Use any of the Microsoft Self-Hosted Agent.
2) Try installing botkskills using following command npm install -g botskills#latest
(Follow the attached screenshots)
3) Try using botskills to verify if the package is available.
I'm not sure if it is supported on a Azure agent, but this looks like a pathing issue.
On a typical machine, in powershell you can run the following to check what your path variable is set to:
$env:path.split(";")
You should typically have something like:
C:\Users\<username>\AppData\Roaming\npm as one of the paths.
For me, bot skills is at:
C:\Users\<myusername>\AppData\Roaming\npm\botskills.ps1
If you don't have that npm path in your path variable, that needs to be remedied somehow. If it's there, then you need to verify that botskills.ps1 is there.
When everything is setup correctly, you can use the following in PowerShell to find the path:
get-command botskills | select path
The error botskills not recognized is because the botskills package installation path is not in the System Environment variables PATH of you local machine. Azure pipeline agent is running as a different user (by default the NetworkService user), and the botskills package is installed by azure pipeline in a different path that unknown to system environment path.
You need to manually add the "path" to the system environment Path for the self-hosted agent machine.
You can also use --prefix to specify a custom npm package installation folder, and make sure add the path to system environment path for the self-hosted agent machine.
npm install botskills#latest -g --prefix C:\custompath\npm
Or you can add the installation path to Environment path in the powershell task using below script.
$env:Path += ";C:\path to botskills installation\npm"
Please check the answer to this thread for more information and the discussion for a similar issue here.

Unable to run packages installed using npm on VM provisioned by Chef

I provisioned my VM on AWS using Chef and installed NodeJS using the NodeJS recipe (https://github.com/redguide/nodejs). When I do a global npm install of any package, I am not able to run that package using command line. Attached the screenshot below.
My poise-javascript cookbook has node_package and javascript_execute resources to take care of all the required path munging for you.
There are two options:
1)add the /usr/local/nodejs-binary-6.3.0/bin/ to PATH variable.
Or
2)Run /usr/local/nodejs-binary-6.3.0/bin/http-server.
The npm package binaries are not added to path by default. I would prefer option 2 to keep the path unpolluted

Is there any way to configure multiple registries in a single npmrc file

Here is my problem. We have a private NPM registry which only works in VPN. I would like to have a fallback registry https://registry.npmjs.org so that when I am out of VPN it works seamlessly.
P.S. Currently I am using npmrc which does a good job in switching between .npmrc files as a workaround
You can have multiple registries for scoped packages in your .npmrc file. For example:
#polymer:registry=<url register A>
registry=http://localhost:4873/
Packages under #polymer scope will be received from https://registry.npmjs.org, but the rest will be received from your local NPM.
On version 4.4.1, if you can change package name, use:
npm config set #myco:registry http://reg.example.com
Where #myco is your package scope.
You can install package in this way:
npm install #myco/my-package
For more info: https://docs.npmjs.com/misc/scope
I believe the top-voted answer might be outdated. As of June 2021, there is a much easier way to do this using npmrc.
Refer to npm Docs.
1. Install npmrc
To install npmrc, on the command line, run
npm i npmrc -g
2. Create your first npm profile
After installing npmrc, you can create a profile to access your custom (maybe company's) registry.
To create an npm Enterprise profile, on the command line, run npmrc -c name-of-profile.
For example, to create a profile called "work", run the following command:
npmrc -c work
To set an npm Enterprise registry for the profile, run the following command, replacing your-company-registry with the name of your company's npm Enterprise registry:
npm config set registry https://registry.your-company-registry.npme.io/
3. Create a profile for the public npm registry
After you have created your npm Enterprise profile, you can create a second profile for a different registry, such as the public npm registry.
To create a profile for the public registry, on the command line, run npmrc -c name-of-profile. For example, to create a profile called "open-source", run npmrc -c open-source.
To set the public registry for your open source profile, run the following command:
npm config set registry https://registry.npmjs.org/
4. Switch profiles with npmrc
To switch profiles, on the command line, run the following command, replacing profile-name with the name of your profile:
npmrc profile-name
Not the best way but If you are using mac or linux even in windows you can set alias for different registries.
##############NPM ALIASES######################
alias npm-default='npm config set registry https://registry.npmjs.org'
alias npm-sinopia='npm config set registry http://localhost:4873/'
For anyone looking also for a solution for authentication, I would add on the scoped packages solution that you can have multiple lines in your .npmrc file:
//internal-npm.example.com:8080/:_authToken=xxxxxxxxxxxxxxx
//registry.npmjs.org/:_authToken=yyyyyyyyyy
Each line represents a different NPM registry
Since it has been a couple years and it doesn't seem possible to do this (using npm alone), a solution to this problem is to use the Nexus Repository Manager (from Sonatype). Nexus supports multiple repositories, lets you order them, and also proxies/caches to improve speed.
A free version and pro/paid version exist. The feature that supports this is described at:
https://help.sonatype.com/repomanager3/node-packaged-modules-and-npm-registries
The relevant information is duplicated below so if/when the above URL/link stops working the information is still here.
A repository group is the recommended way to expose all your npm registries repositories from the repository manager to your users, without needing any further client side configuration. A repository group allows you to expose the aggregated content of multiple proxy and hosted repositories with one URL to npm and other tools.
It lets you create private npm registries
A private npm registry can be used to upload your own packages as well as third-party packages.
And
To reduce duplicate downloads and improve download speeds for your developers and CI servers, you should proxy the registry hosted at https://registry.npmjs.org. By default npm accesses this registry directly. You can also proxy any other registries you require.
So a quick bulleted list of things you do to get this working is:
Install Nexus
Create a local/private repo (or point to your private repo on another server)
Create a GROUP that lists your private repo, and the public repo.
Configure your $HOME/.npmrc file to point to the "GROUP" just created.
Publish your private npm packages to the local repo.
Users now can run a one time setup.
npm config set registry https://nexus/content/groups/GROUP
Then users can install both public or private packages via npm install.
npm install my-private-package
npm install lodash any-other-public-package
And both your public and private packages can be installed via a simple npm install command. Nexus finds the package searching each repo configured in the group and returns the results. So npm still thinks there is just one registry but behind the curtain there are multiple repos being used.
IMPORTANT NOTE: When you publish your components, you'll need to specify the npm publish --registry https://nexus/content/repositories/private-repo my-private-package command so your package is published to the correct repo.
You can use multiple repositories syntax for the registry entry in your .npmrc file:
registry=http://serverA.url/repository-uri/
//serverB.url/repository-uri/
//serverC.url/repository-uri/:_authToken=00000000-0000-0000-0000-0000000000000
//registry.npmjs.org/
That would make your npm look for packages in different servers.
Some steps you can try. (its how we do it at my workplace)
Create a registry group with two (or more) repository source address. One would be your internal private and the other a proxy to npmjs giving priority to the internal one.
Make this group your registry in the .npmrc file. This way npm will always try to get it from the internal one, if not found get it from the proxy
Hope that helps.
I encounter the same problem when my company set up its own registry, so I heavily rework on proxy-registry into proxy-multi-registries to solve this problem. Hope it will also helps you.
As of 13 April 2020 there is no such functionality unless you are able to use different scopes, but you may use the postinstall script as a workaround. It is always executed, well, after each npm install:
Say you have your .npmrc configured to install #foo-org/foo-pack-private from your private github repo, but the #foo-org/foo-pack-public public package is on npm (under the same scope: foo-org).
Your postinstall might look like this:
"scripts": {
...
"postinstall": "mv .npmrc .npmrcc && npm i #foo-org/foo-pack --dry-run && mv .npmrcc .npmrc".
}
Don't forget to remove #foo-pack/foo-org from the dependencies array to make sure npm install does not try and get it from github and to add the --dry-run flag that makes sure package.json and package-lock.json stay unchanged after npm install.
My approach was to make a slight command line variant that adds the registry switch.
I created these files in the nodejs folder where the npm executable is found:
npm-.cmd:
#ECHO OFF
npm --registry https://registry.npmjs.org %*
npm-:
#!/bin/sh
"npm" --registry https://registry.npmjs.org "$#"
Now, if I want to do an operation against the normal npm registry (while I am not connected to the VPN), I just type npm- where I would usually type npm.
To test this command and see the registry for a package, use this example:
npm- view lodash
PS. I am in windows and have tested this in Bash, CMD, and Powershell. I also
I use Strongloop's cli tools for that; see https://strongloop.com/strongblog/switch-between-configure-public-and-private-npm-registry/ for more information
Switching between repositories is as easy as : slc registry use <name>
I had the same issue and I've tried many solutions that didn't work, now i encountered that by using different scoops for my npm private packages, in that way in can use multiple registries with same .npmrc file like that :
.npmrc : (You can put as many packages you want)
#scop1:registry=https://gitlab.example.com/api/v4/projects/<project1_id>/packages/npm/
#scop2:registry=https://gitlab.example.com/api/v4/projects/<project2_id>/packages/npm/
//gitlab.example.com/api/v4/projects/<project1_id>/packages/npm/:_authToken=${GITLAB_TOKEN}
//gitlab.example.com/api/v4/projects/<project2_id>/packages/npm/:_authToken=${GITLAB_TOKEN}
No, NPM does not support multiple registry except for scoped one.
Refer to: https://docs.npmjs.com/cli/v7/using-npm/scope

How to use npm in an environment with restricted internet access

In a restricted environment where not every user has access I would like to be able to use npm offline where ever possible.
My idea is to point the global config at a shared cache directory so that power users can do installs and the dependencies will end up in the cache directory. Other users can then do npm offline installs for anything previously in the cache.
So 2 Questions:
Will this work?
Short of setting up my own local npm repository is there an easier way?
Per documentation:
npm install (with no args in a package dir)
npm install <tarball file>
npm install <tarball url>
npm install <folder>
npm install <name> [--save|--save-dev|--save-optional]
npm install <name>#<tag>
npm install <name>#<version>
npm install <name>#<version range>
npm i (with any of the previous argument usage)
As such, npm allows you to do:
npm install /path/to/folder/containing/ node_modules
For example: npm install ~/Downloads/http-proxy, provided that the node_modules folder resides within http-proxy.
You could set your repository up on an internal (accessible) server and direct people to download by the same name from there.
Thanks for the answers. What I've ended up doing is using https://github.com/rlidwka/sinopia
This acts as a mirror repository. I can give this process internet access and not other users. Then I set a environment variable for all users to point their npm repository at the sinopia instance.
Early days but this seem to be working well.
r3mus is right. Though, for each user it would result in some cognitive overhead and possibly management issues.
What might work better is to have a corporate hosted npm repository (as described here: http://clock.co.uk/tech-blogs/how-to-create-a-private-npmjs-repository) and then just have the users change (once) their registry settings via npm set registry http://yourregistry.com
For build servers, a reasonable strategy is to symlink the node_modules directory against an existing directory where the modules have already been installed.
e.g. my powershell script might read something like this
If (-Not (Test-Path node_modules))
{
& cmd /c mklink /d /j node_modules D:\npm-cache\node_modules
Write-Verbose "Symlinked node_modules"
}

Resources