Access Private NPM Repo with DoD CAC

We're looking for a way we can get the npm command to use our DoD CACs (PKI, PIV, X.509, Smart Card) to authenticate with a privately-hosted repo, configured with PKI-based mutual authentication. Is this possible?

We're looking for a way we can get the npm command to use our DoD CACs (PKI, PIV, X.509, Smart Card) to authenticate with a privately-hosted repo, configured with PKI-based mutual authentication. Is this possible?

Introduction to npm

A simple guide to npm, with a briefly introduction to the node package manager, In September 2019 over 1 million packages were reported beign listed in the npm registry, making npm the biggest single language code repository!

Original post at NPM Introduction

Introduction to npm

npm is the standard package manager for Node.js.

There are many things that npm does. It allows for seamless node.js package management. You can install, share and manage node.js packages.

npm consists of three components:

  1. Website
  2. Registry
  3. CLI

In the npm official Website you can find packages, view documentation, share and publish packages.

The npm Registry is a large database consisting of packages. In September 2019 over 1 million packages were reported being listed in the registry, making npm the biggest single language code repository! and you can be sure there is a package for (almost!) everything. It started as a way to download and manage dependencies of Node.js packages, but it has since become a tool used also in frontend JavaScript.

The CLI is the command line that helps in interacting with the npm for installing, updating and uninstalling packages and also managing dependencies.

Note: Yarn is an alternative to npm. Make sure you check it out as well.

Installation

npm comes with Node.js, this means you don’t have to install it separately. Go to the official website to Download Node.js and install it, if you haven't already installed it on your system.

After installing node, You can check the version of node and npm by running

node --version
npm --version

package.json

The package.json is the project manifest file. Using the package.json you can manage dependencies and write scripts. It has all the meta data about the project.

Init Project

Note: you only need to do this if you are starting a new project, if not take a look if the package.json file already exist

For create a package.json, first head over to your project folder. You can create package.json by running the command

npm init

It asks you for some data like package name, description, version, author, license, etc. You can just press enter for defaults.

Or to quickly create a package.json file. You can use the command

npm init -y

Installing all dependencies

If the project has a packages.json file, by running the command

npm install

it will install all the dependencies that the project needs, that is to say, the packages from the dependencies and devDependencies at the package.json, in the node_modules folder, creating it if it doesn't already exist.

The node_modules is the folder in which our local packages are installed. There will be a new file named package-lock.json. This file contains the exact version of the package, unlike package.json which contains the semantic version.

Installing a single package

You can also install a specific package by running

npm install <package-name>

Often you'll see more flags added to this command:

  • --save installs and adds the entry to the package.json file dependencies (default as of npm 5)
  • --save-dev installs and adds the entry to the package.json file devDependencies
  • --no-save installs but not doesn't add the dependency to your package.json file.

The difference is mainly that devDependencies are usually development tools, like a testing library, while dependencies are bundled with the app in production.

Installing a single package Globally

A globally installed packages works anywhere on the machine. To install global packages you’ve to use -g flag.

Generally, any packages you use in your project have to be installed locally. And packages you use in the command line are to be installed globally.

The command for the local and global packages are same except that you have to use -g flag for global packages.

For example you can install nodemon globally, that is a utility that will monitor for any changes in your source code and automatically restart your server, it's great idea for development

npm install -g nodemon
Versioning

In addition to plain downloads, npm also manages versioning, so you can specify any version of a package, or require a version higher or lower than what you need.

Maybe you could find that a library is only compatible with a major release of another library. Or a bug in the latest release of a lib, still unfixed, is causing an issue.

Specifying an explicit version of a library also helps to keep everyone on the same version of a package, so that the whole team runs the same version until the package.json file is updated.

In all those cases, versioning helps a lot, and npm follows the semantic versioning (semver) standard.

All the package versions are represented with three digits

  • The first digit is major
  • The second is minor
  • The third is patch.

The patch(~) is updated for bug fixes.

The minor(^) is updated for every new functionality that doesn’t break the existing code.

The major is updated for big changes. These generally break the existing code.

In the package.json, when you install a package, you will see a caret^ symbol by default. This indicates that when a user is downloading your project, the package will be updated to the latest minor version. Same applies to patch. If we don’t include any symbol then exact version is downloaded. To get the latest major version, asterisk * is used. But you don’t want to do this as the major version can break your code.

To install either major, minor, patch (or) exact version, you can use the command

npm install <package-name>@x.y.x

For example, let's install lodash

There are several ways to accomplish this. First, let’s start with the basic

npm install lodash

This command installs lodash and fetches the latest available version.

If you know the exact version of the package that you need, you can append it to the package name after the @ character

npm install [email protected]

If you don’t know the exact version of the package, npm also allows using semantic ranges to define the version

npm install [email protected]^4.0.0

This command will install the latest 4.x.x version.

Both examples don’t modify package.json and don’t add installed modules to the list of dependencies. We must use --save to add the installed module to the package.json dependencies and --save-dev to add it to devDependencies.

If you install a module without defining a specific version, npm will add the semantic range to the package.json as is. To prevent this, use --save-exact flag in addition to --save or --save-dev. This flag will force npm to store the exact module version in the package.json.

Updating packages

Since we have installed packages sometimes we need to update our packages to get new features. To do that, you’ve to run

npm update

npm will check and update all the packages listed to the latest version that satisfies your versioning constraints.

Updating a single package

For update a single package you can specify it to update as well

npm update <package-name>

Uninstall a single package

Sometimes you don’t need a particular package and you want to remove it. It’s not a good idea to manually remove the package from the node_modules folder as it can be a dependency for the other packages. To safely uninstall a package you’ve to run

npm uninstall <package-name>

This will completely remove everything npm installed on its behalf.

You must use the corresponding flag to save the changes in the package.json.

For example if you want to uninstall lodash from the dependencies of package.json you should run

npm uninstall lodash --save

Or from the devDependencies

npm uninstall lodash --save-dev
List installed packages

To get the list of installed packages, run the command

npm run list

This will list all the packages including its dependencies. The packages installed by you will be in the depth 0. Its dependencies will be in the depth 1 and further dependencies will be in the depth 2 and so on. To get packages of a certain depth, use the command

npm list depth <number>
Running Tasks

The package.json file supports a format for specifying command line tasks that can be run by using

npm run <task-name>

For example:

{
  "scripts": {
    "start-dev": "node lib/server-development",
    "start": "node lib/server-production"
  },
}

It's very common to use this feature to run Webpack:

{
  "scripts": {
    "watch": "webpack --watch --progress --colors --config webpack.conf.js",
    "dev": "webpack --progress --colors --config webpack.conf.js",
    "prod": "NODE_ENV=production webpack -p --config webpack.conf.js",
  },
}

So instead of typing those long commands, which are easy to forget or mistype, you can run

npm run watch
npm run dev
npm run prod
Getting Help

npm CLI has built -n help command. You can access it by

npm help

To get help for a particular command run

npm <command> -h

You can also search npm documentation for help. To do that use

npm help-search <command>

Now you’ve learned all the basics of npm. To know more about npm you can go to the documentation in the official Website. Now you can start using it in your own projects, happy hacking!

Thanks for reading! ❤

If you liked this post, please do share/like it with all of your programming buddies!

Is npm !== npx

Is npm !== npx

Recently when I started getting into React I saw a lot of people (including myself) getting confused when seeing npx instead of the very well known npm. ![This is image...

Recently when I started getting into React I saw a lot of people (including myself) getting confused when seeing npx instead of the very well known npm.

Some of us found it weird but didn’t give much thought, others thought it was a typo and even went into the trouble of “fixing” it by running npm instead of npx.

When I see something happening more than once, I consider it as being worth to be explained. That’s why this article, to all who had the same misunderstanding as me.
what is the NPM?
As we might already know, npm is a package manager for Node.js whose goal is automated dependency and package management.

It means that we can specify all our dependencies (packages) for a project in the package.json file and whenever someone has to install the dependencies for it, they should just run npm install and voila!

It also provides versioning i.e. it makes it possible to specify which versions of the dependencies our project depends upon, so we can, for the most part, prevent updates from breaking our project or use our preferred version.
what is NPX?
What npx does is the following:
By default, it first checks if the package that is to be executed exists in the path (i.e. in our project);
If it does, it executes it;
Else, means that the package has not been installed, so npx installs its latest version and then executes it;
This behavior, that is explained above, is the default one of npx, but it has flags that can be used to prevent it.

For example, if we run npx some-package --no-install means that we're telling npx that it should only try to execute the package named some-package, without installing it if it has not been installed before.

Example
Let's say we have a package named some-package and we want to execute it.
Well, without npx, to execute a package we would have to do it by running it from its local path, like this:

package.json file while become this shape.
{
"name": "something",
"version": "1.0.0",
"scripts": {
"some-package": "./node_modules/bin/some-package"
}
}

to run it in npm npm run some-package.
in npx .npx some-package

NPM vs. NPX

NPM vs. NPX

A quick explanation of the difference between npm and npx. Are there any benefits of using npx instead of npm? I know you were trying to find the answer for the above questions and at the end, you landed up on this page. I will try to answer these questions for you. And at the end of the article, I am sure that you will get the answer to your questions. I hope you will find this post useful. 

Introduction

We all are using npm as our package manager. It is easy, right? But with the version [email protected], when you install the npm, it installs a new package called npx. Have you ever thought about what it is? And why it is needed? Are there any benefits of using npx instead of npm? I know you were trying to find the answer for the above questions and at the end, you landed up on this page. I will try to answer these questions for you. And at the end of the article, I am sure that you will get the answer to your questions. I hope you will find this post useful.

What we are going to do

We will be creating two applications and installing the mocha package in both applications so that we can run some tests.

  1. mocha-example-npm
  2. mocha-example-npx

npm-npx

Coding with mocha-example-npm application

Let’s try to create a new folder named mocha-example-npm and open it in my favorite code editor, which is vscode. Once you open the folder, you can install mocha by running this command.

  1. npm install mocha
    Let’s create a folder called test.

  2. mkdir test
    Let’s create a file called test.js.

    code test/test.js

And paste the below sample test in it.

var assert = require('assert');  
describe('Array', function() {  
    describe('#indexOf()', function() {  
        it('should return -1 when the value is not present', function() {  
            assert.equal([1, 2, 3].indexOf(4), -1);  
        });  
    });  
});  

By seeing the code, you might have already found that the test will pass the indexOf (4) as -1. Now how do we check this? So to run the test we need to run mocha right? Let’s do it.

If you just type mocha in the terminal, you will get an error as below.

  1. mocha - The term 'mocha' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1  
+ mocha  
+ ~~~~~  
+ CategoryInfo : ObjectNotFound: (mocha:String)[], CommandNotFoundException  
+ FullyQualifiedErrorId : CommandNotFoundException  

It is saying that mocha is not a recognized command. To fix this you have three options below.

  • Install mocha globally, so that the command will be recognized globally
[email protected] C:\Program Files(x86)\nodejs\node_modules\npm  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npm\mocha-example-npm> npm i mocha -g  
C:\Users\Sibeesh\AppData\Roaming\npm\mocha -> C:\Users\Sibeesh\AppData\Roaming\npm\node_modules\mocha\bin\mocha  
C:\Users\Sibeesh\AppData\Roaming\npm\_mocha -> C:\Users\Sibeesh\AppData\Roaming\npm\node_modules\mocha\bin\_mocha  
+ [email protected]  
added 24 packages from 436 contributors in 3.458s  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npm\mocha-example-npm> npm list -g mocha  
C:\Users\Sibeesh\AppData\Roaming\npm  
`-- [email protected]  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npm\mocha-example-npm> mocha  
Array  
#indexOf()  
√ should return -1 when the value is not present  
1passing(14ms)  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npm\mocha-example-npm>  
  • Use the path to mocha from node_modules

    ./node_modules/mocha/bin/mocha

  • Configure test in your package.json file as follows.

"scripts":{  
   "test":"mocha"  
}  
So that you can run _npm test_ command, and it will take the mocha files from your node_modules folder.

Coding with mocha-example-npx application

So, we have understood the problem we have using npm and we have three solutions to fix it. Now, let’s try using the npx instead of npm. Let’s open the folder and run npx mocha. The result is a warning as it is trying to find the folder test in the solution and then the tests.

  1. npx: installed 24 in 6.203s
  2. Warning: Could not find any test files matching pattern: test
  3. No test files found

Let’s create a test folder, test.js file and write a test in it.

PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> mkdir test  
Directory: F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx  
Mode LastWriteTime Length Name  
---- ------------- ------ ----  
d----- 20-10-201806:26 PM test  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> code test/test.js  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx>  

Let’s run the command npx mocha now, and you will get the output as below.

PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> npx mocha  
npx: installed 24 in 4.142s  
Array  
#indexOf()  
√ should return -1 when the value is not present  
1passing(12ms)  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> 

As you can see that our tests are passed. But are you seeing any node_modules folder or any packages are being added to your solution?

What is npx?

Now, let’s just summarize what npx is. It is an npm package runner. We all know that we are installing the packages to our solution from the location called npm registry and using it. And the npx has been designed in a way that we can directly use the package from the npm registry without even installing it in our solution. You may be thinking why is it needed?

Let me give you an example, as I mentioned in the background section of this article, we can create a simple React application with the help of Create-React-App from FaceBook. And this is used only for creating the application, and once we create the application, we no longer need this. If you use npm, you will have to install this package either globally or locally before you use this, or else you will get an error.

Wouldn't it be good, if we could just use this create-react-app package from the npm registry and create the application in our local machine? And that’s where npx comes in. With the help of npx, we can reduce the size of our node_modules and I strongly believe that this is a huge benefit.

It is smart enough to identify whether the package you are trying to get from the npm registry is already there in your machine, either globally or locally. If the package is available in your machine, it will take it from there.

What if mocha is installed globally or locally and we run the command npx mocha?

Let’s try to install mocha globally and run the command npx mocha. Before that, let’s just make sure that we haven’t installed mocha yet.

PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> npm list mocha  
[email protected] F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx  
`-- (empty)  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> npm list -g mocha  
C:\Users\Sibeesh\AppData\Roaming\npm  
`-- (empty)  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx>  

Now, let’s just install mocha globally

PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> npm i mocha -g  
C:\Users\Sibeesh\AppData\Roaming\npm\mocha -> C:\Users\Sibeesh\AppData\Roaming\npm\node_modules\mocha\bin\mocha  
C:\Users\Sibeesh\AppData\Roaming\npm\_mocha -> C:\Users\Sibeesh\AppData\Roaming\npm\node_modules\mocha\bin\_mocha  
+ [email protected]  
added 24 packages from 436 contributors in 3.033s

Try to run npx mocha again,

PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx> npx mocha  
Array  
#indexOf()  
√ should return -1 when the value is not present  
1passing(12ms)  
PS F:\SibeeshPassion\Articles\NPMvsNPX\npx\mocha-example-npx>  

You are not getting any information related to the installation (for example npx: installed 24 in 4.142s).

Conclusion

Thanks a lot for reading. I will come back with another post on the same topic very soon. Did I miss anything that you may think is needed? Did you find this post useful? I hope you liked this article. Please share with me your valuable suggestions and feedback.

Source Code

The source code can be found here.