NPM package versioning [#16]

Either you are working on an application the relies on NPM packages such as Angular apps or you are building your own NPM package, you will have to get familiar with Semantic Versioning. The Semantic Versioning spec allows developers that use these packages know the specific version of the package they are using.

Semantic Versioning follows the pattern MAJOR.MINOR.PATCH, where

  • A major release breaks backwards compatibility
  • A minor release contains new features but is backwards compatible
  • A Patch release fixes a bug without breaking backwards compatibility.

You are working on an application that relies on NPM packages

In this case it is important that you have a clear understanding of how packages are installed in your app and what versions it will accept. To explain this we will create a small application using Express. We will use the Express Generator wich will create a basic app. You can find information about the Express Generator here.

These are some details about my environment in case you need to tweak something if you are running in a different environment.

  • OS: Windows
  • Source Code Editor: Visual Studio Code
  • Node Version: v14.16.1
Create the Express app

This command will create a folder structure and an Express app called myapp.

npx express-generator --view=pug myapp

You should get a folder structure and a package.json similar to these:

Express app - initial folder structure

You will notice that some package versions have an "~" on the front such as the express package, and some others don't such as the pug package. I will get to the details about this later in the article.

Install the NPM packages

You may have notice that we have a package.json file but we don't have a node_modules folder with all the required dependencies. Now we will install the NPM packages we need to run this application. Run the following command:

npm install

After running the command you will notice that the node_modules folder and a package-lock.json file were added. If you open the package-lock.json and the package.json files, you will notice that the actual versions installed for your application are not the same specified in the package.json file.

For express the package.json file specified "~4.16.1" but the actual version the project has installed is 4.16.4

Express app - express version

For pug the package.json file specified "2.0.0-beta11" and the actual version the project has installed is the same "2.0.0-beta11".

Express app - pug version

Why is that? Well the reason is that npm have ~ indicates that the npm i will look for the latest minor version available.

Description Sympol Example
Exact releases "pug": "2.0.0-beta11"
Patch releases ~ "express": "~4.16.1"
Minor releases ^ "express": "^4.16.1"
Major releases * "express": "*4.16.1"

The roll of the package-lock.json

The package-lock.json file describes the exact tree of dependecies that was generated and installed. This file should be committed to your source repository for the folling reasons:

  • Guarantee that other people working on the project install the same dependencies.
  • Time-travel to previous states of application, dependencies (node_modules) may have change along the live of the project.

Versioning our own applications

So far we have talked about the NPM packages and its versions. What about the version of our web app, if you go back to your package.json file you will notice a version property is set to 0.0.0. This is the version of our application, let's change it to 1.0.1 (let's imagine that it is our second release and 1.0.1 is fixing a bug). We will also make a change in the template to display the version. Your package.json and index.pug files should look like these:

Display App version using package.json
Run the web app
npm start

Open your browser and navigate to localhost:3000, you should see the home page.

Express appn