What's the best way to deploy a npmjs Private Module? - npm

npmjs recently released their private npm modules feature which looks pretty cool.
To publish or fetch a private module from npm you need to have an authenticated npm client using npm login so the .npmrc file will get updated or created with the access token.
What is the best practice to deploy or CI an application that uses a private module?

The best way to do this is to include the .npmrc file but replace the auth token with an environment variable. Step 4 of this tutorial shows you how to do this and should work for any CI/deployment scenario.
If you are using Heroku, then you can follow Step 5 to set the environment variable. If not, just figure out how you configure env variables for the service you're using.

Related

Yarn doesn't authenticate Gitlab Private package

I have two private packages hosted on GitLab. One of the installs correctly the other one gives error 404 which in my experience at GitLab means unauthorised
I've checked with yarn install --verbose that it is using the right registry
I've cleared the cache of yarn
I've tried npm
I've tried adding both project level tokens and instance level tokens
This is my .yarnrc
"#myscope:registry" "https://gitlab.com/api/v4/packages/npm/"
"//gitlab.com/api/v4/packages/npm/:_authToken" token
always-auth true
lastUpdateCheck 1660229364662
And this is my .npmrc
"#myscope:registry"="https://gitlab.com/api/v4/packages/npm/"
"//gitlab.com/api/v4/packages/npm/:_authToken"="token"
always-auth=true
Note that these are in my home directory. This is intentional because if I add them at project level I need to use an env var but that complicates things a lot because this project is build as part of a Gradle task
Also note that the first project had similar problems when I wanted to install it the first time but then I managed to get it solved. I'm not sure what I've done or what helped at the end but since then it installs without any problems
Seems like there was an issue with GitLab because I generated a new token and it works now. (I don't have an expiration date set so..)

Private github npm repositories on Netlify

I've been trawling documentation on Netlify's site for how to deploy a node application (specifically a Vue application) which has a private npm repository as a dependency.
I have an .npmrc file setup as follows:
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}
#my:registry=https://npm.pkg.github.com
I also set the GITHUB_TOKEN variable in my build process's environment variables to the correct value.
However, the build fails.
There is an outline of how to achieve a successful build with a private Github package repository here: https://docs.netlify.com/configure-builds/repo-permissions-linking/#npm-packages.
However, it's still unclear as to what I need to do specifically to both my package.json file and also how to configure the build process' environment variables ...
Could anyone show me a full working example which doesn't leave me scratching my head?
Do I add:
"package-name": "git+https://<github_token>:x-oauth-basic#github.com/<user>/<repo>.git"
to the dependencies section of the package.json?
If yes, how do I then hide my <github_token> and provide the build process with this in Netlify?
How do I also get the same process working locally?
Why can't Netlify just inject the GITHUB_TOKEN into my .npmrc file so I have parity with my local development environment?

How can I shim access to a private repository with scoped npm packages on a machine that can't access it?

Let's say I have a private, scoped NPM repository that lives behind a corporate firewall. I'd like to set my project up on another computer that will not connect to the VPN, so it will not be able to access that private repo.
How can I set up my project to easily import those dependencies from local folders and/or my local npm cache and skip the private repo?
That is, if my package.json file has...
"dependencies": {
"#privateRepo/some-library-framework": "4.2.1"
}
... and I can't get to the server, but I can get the files that are needed and would've been installed from another node_modules folder that lives on a machine that can access the repo.
I tried taking the files from the packages in #privateRepo and using npm cache add D:\path\to\lib\with\packageDotJsonInside for each of them, but still got...
Not Found - GET https://registry.npmjs.org/#privateRepo%2some-library-framework - Not found
... when I tried to npm i the rest.
I think that means that I need to set something up in .npmrc like is described here...
registry=https://registry.npmjs.org/
#test-scope:registry=http://nexus:8081/nexus/content/repositories/npm-test/
//nexus:8081/nexus/content/repositories/npm-test/:username=admin
//nexus:8081/nexus/content/repositories/npm-test/:_password=YWRtaW4xMjM=
email=…
... where you'd normally set up auth, but where you're also setting up the URL to a scoped package. I think I want to set up #privateRepo:registry=http://localhost/something/something here.
But I think that also implies I would at least need to create a local webserver (or npm repo?) to answer requests (and then maybe I'm looking for something like verdaccio?).
So, simplest case, is there a way to force the app to use the cached version or is there more I need to shim? If not, what's the easiest way to create a local repo to serve those packages in the place of the private repo?
Seeing nothing better, the easiest answer does seems to be setting up a local npm repo. You can then set up your .npmrc to point to localhost for the scoped private registry instead of the "real" version behind a VPN.
And as it turns out, Verdaccio actually does exactly this -- you could also use it to host a "real" private repo, including behind your firewall, but installing on your dev box will allow you to provide your npm packages to any new codebase locally.
This is described in some detail by this video that's linked on Verdaccio's docs site. Here's the quick version:
Install verdaccio: npm install --global verdaccio
Run verdaccio: verdaccio
You can then check out its interface at http://localhost:4873/ (or elsewhere if you changed defaults)
Create a user: npm adduser --registry http://localhost:4873
Login: npm login --registry http://localhost:4873
You can now log in as that user on the web UI too, if you want.
Navigate to your packages' files. Navigate into the folder that's package specific.
That is, if you pull all of your packages from another project's node_modules, you need to go into each folder where the individual package's package.json file lives to publish it.
Publish the package: npm publish --registry http://localhost:4873
You can double-check that it "took" by refreshing the web UI.
Repeat for each additional package.
That's it! You now have an npm repo for the packages you can use to remove the VPN requirement for running npm i. Just schlep the new versions of the packages over to your local npm and publish them as appropriate.
You will need to set up a scoped entry for this registry in your .npmrc, but you were already doing that for your repo behind the firewall, so no big deal, right?
Ready to move the check for a better answer, but this seems like it oughta work.

Is it possible to have two private registries with different authentication data in .npmrc?

There is an npm package on artifactory_1 which is private. This means that the _auth property in .npmrc contains the authentication data for artifactory_1 in base64 and always-auth is set to true. This way the npm install works, the private package can be downloaded from artifactory_1 because the authentication data is provided from the _auth property.
Now I have an other private package on an other private artifactory (may it be artifactory_2). I want to use the private package of artifactory_2 in the same project, where artifactory_1 is already configured with its authentication data.
This means, that I should somehow add the new registry and the authentication data of it to the .npmrc. It should be possible to use the private package from artifactory_1 and the private package from artifactory_2 at the same time.
It is documented here, how is it possible to handle one private package in a project.
But I do not find any documentation/example for more private packages from different artifactories.
Any idea how should this be done? Is this even possible, what I want to do?
I did not make it to use repos from two different artifactories. I migrated the content of the first artifactory into a repo of the second artifactory. After that I was able to create a virtual repository, that showed the content of the two repos as one. This virtual repo is set up in my project as registry and this way I'm able to install the content of the two repos.

Using auth tokens in .npmrc

I have a project where we use font awesome 5 library. I followed the instructions that are written here and added an .npmrc file with my auth token.
Is this a safe behaviour to put this in a repo? I want the devs to have access to it, but if the repo goes public we might be exposing the token.
What is the best practice in situation like this?
UPDATE 2021-05-02
This answer remains questionable - see the comments below. I no longer have access to a private ($paid) npm account anymore, so I can no longer test to answer questions.
Perhaps try #konyak's answer.
It is definitely NOT a safe behavior to put the token in any git checked file, including .npmrc.
Below are the steps your team can take to safely leverage your npm token.
There are two different environments to consider:
each developer's local dev machine
the app's deployment platform
local dev
Following the Global Set Up instructions you linked to in your question, is not the solution.
Create the .npmrc file similar to the "Per project" instructions, but substitute your real token with a variable name, prefixed by $. ie:
#fontawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=$TOKEN
npm will detect an environment variables file named .env. So, in a .gitignored .env file, add your secret key value pair, ie:
TOKEN=ABC123
You can also prefix the variable name with "NPM_CONFIG_", according to the npm-config docs, ie:
NPM_CONFIG_TOKEN=ABC123
Now, when the dev runs npm i, font-awesome dependencies will load from the private repo.
NOTE: Don't follow the current npm-config docs about the environment variables syntax! See this stack overflow answer, ie:
👎 BAD npm-config ENVIRONMENT VAR SYNTAX 👎
${TOKEN}
👍 GOOD npm-config ENVIRONMENT VAR SYNTAX 👍
$TOKEN
app deployment platform
Do all the steps from the local dev section above, PLUS:
create an environment variable on the platform with the same name as in the .npmrc file.
If your app host is Netlify, see their Build Environment Variables docs.
https://docs.npmjs.com/using-private-packages-in-a-ci-cd-workflow
Export your secret token into your session, e.g., export NPM_TOKEN="00000000-0000-0000-0000-000000000000"
Inside your ~/.npmrc, add //registry.npmjs.org/:_authToken=${NPM_TOKEN}
I put the relevant config line, with the token in plaintext, in a .npmrc file in my home directory. You can then use filesystem / OS permissions to protect it, avoid accidentally checking it in to source control, and NPM will read it automatically with no further action on your part.
In the project directory, we have .npmrc with a scoped registry declaration only (#fontawesome:registry=https://npm.fontawesome.com/), and a separate ci.npmrc which has that plus the variable-substitution authToken assignment:
#fontawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=$FONTAWESOME_NPM_TOKEN
The CI build job just has to replace .npmrc with ci.npmrc before doing anything with npm, and set a secret environment variable with an auth token assigned to the appropriate service account.