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.
The jargon
Node: Node (or Node.js) is a âruntime environmentâ. Itâs a server-side environment that runs JavaScript code. The same way your browser has a JavaScript engine, well Node has one as well. This allows you to execute JavaScript code, like scripts, outside of a browser environment.
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.
Managing dependencies
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 withnpm 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), runnpm install, and have the exact same packages as you did. Think of it as a snapshot of all your projectâs dependencies.
Using dependencies
Alright, so letâs recap a little bit what we just learned.
-
Node is an environment to execute JavaScript code. It has a package manager called npm, which is used to install (and reinstall) packages.
-
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 innode_modules.
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 and faker.
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 ./node_modules/.bin/cypress (or $(npm bin)/cypress which is the exact same thing).
Faker, on the other hand, does not provide an executable. It gives you JavaScript utilities you can import in your JavaScript code. You import that dependency doing import faker from 'faker' in your JavaScript files. Node can magically resolve 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.
Wrapping up
Alright, so letâs sum up what we just learned:
Some packages provide executables, some donât. All packages providing an executable can be executed with ./node_modules/.bin/<package>.
Most packages do not provide a command-line executable, and are made to be imported within a JavaScript file. This can be done 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!