My partner has started getting into test automation and has had fun playing with Cypress, Backstop and Faker recently. However, the whole Node/npm/npx jargon was very obscure to them, so I wrote the little beginner’s guide you can find below.
npm: npm is the package manager for Node (despite claims it doesn’t stand for “Node Package Manager”). All languages have a package manager (Java has Maven, PHP has Composer, Ruby has RubyGems, etc.). Npm allows you to manage Node dependencies (packages), such as installing and removing them. Npm comes bundled with Node by default, so you don’t have to install it yourself.
Packages: Packages are versioned little bundles of code that people write and publish for other to use. Cypress and Faker, amongst many many others, are packages (and big ones at that).
npx: npx is another command-line utility provided by npm. It’s a bit of an all-in-one command to execute the binary (see below) of the given package name. It will try within the local project if installed, or globally on your machine if installed, or it will temporarily install it otherwise.
When you want to use a package, such as Cypress or Faker, you need to install it. There are two ways to do that: you can install it globally on your machine (with the
-g option) which is usually discouraged because a little obscure and not very manageable. Or you can install locally for your project. This is the recommended option.
When you do
npm install <package> in a directory that has a
package.json file, it will do 3 things:
It will add a line inside your
package.jsonfile to note that the package you just installed is now a dependency of your project. That means your project relies on it.
It will add the package’s code, as well as the code of all the dependencies of that package (and their dependencies, and so on and so forth) into a directory called
node_modules. This automatically-generated directory contains the source code of all the dependencies of your project. It is usually listed in
.gitignoreso that it doesn’t get committed (as it’s freaking huge and not your own code). You can safely delete this directory and reinstall all the dependencies of your project with
npm installat any time. “Have you tried reinstalling your node_modules?” is basically the debug-101 of projects using Node. 😅
It will generate (or update) a file called
package-lock.json. This is an automatically generated file that should never be updated by hand. It contains the version of all your dependencies (as well as their dependencies, and the dependencies of your dependencies, and so on and so forth). This file is a manifest that makes it possible for someone to come after you (or yourself), run
npm install, and have the exact same packages as you did. Think of it as a snapshot of all your project’s dependencies.
Alright, so let’s recap a little bit what we just learnt.
A project usually has dependencies, because not everything should be coded from scratch. These dependencies are installed through npm, and listed in the
package.jsonfile. When installed, their code is in
Okay, so now that we have dependencies installed for our project, how do we use them? Well, that depends what these dependencies do. Let’s take two different examples:
Cypress is a tool. It gives you commands like
cypress open and
cypress run. That’s what we call a “binary”. Basically it means it gives you something you can execute from your terminal. This executable is exposed by Cypress in the
node_modules/.bin folder. Any package that provides an executable will be located in that folder. That’s why you can run
$(npm bin)/cypress which is the exact same thing).
from 'faker' by going into
node_modules/faker and finding the relevant files. That’s pretty handy so you don’t have to do
import faker from './node_modules/faker/lib/something/specific/to/faker/index.js.
Alright, so let’s sum up what we just learnt:
Some packages provide executables, some don’t. All packages providing an executable can be executed with
import something from '<package>'. What is being imported depends on the package and can be figured out by reading its documentation.
I hope this helps!