Article
0 comment

What you should know about semantic package versioning in SPFx

There are many blog posts out there that show how you can install packages to your SPFx project. Many of those projects tell you that you have to install exactly this specific version.

NPM Semantic Versioning

To give you an example upgrading your rush stack compiler in an existing project you can use the following line of code.

Install using an exact version

First remove the old package: (Currently it is the rush stack compiler 2.9)

npm uninstall @microsoft/rush-stack-compiler-2.9

This command removes the compiler from package.json, package-lock.json and from the node_modules.

Let’s install now the new typescript version 3.3 and the rush-stack-compiler also in version 3.3.

Rush Stack Compiler on NPM

Rush Stack Compiler on NPM

So heading over to npmjs.org and look up the version.

By the time of writing this blog post, it is the version 0.2.13. So let’s install an older version through the following command.

npm install @microsoft/rush-stack-compiler-3.3@0.2.7 --save-dev --save-exact

So now your project is bound to this specific version only. Yes, it works but is not the smartest way to install a package. Let’s say you haven’t touched your project in a while and you perform an NPM outdated.

Result of npm outdated with exact version

So in case of the rush-stack-compiler, there are a few minor version in between the currently installed version and the latest online version. The last number identifies that there was published some patches that solve problems.

No, you can reinstall the package manually.

npm install @microsoft/rush-stack-compiler-3.3@0.2.13 --save-dev --save-exact

It upgrades your project to the latest version, and you stay with this version forever. It is a valid approach to install packages like this, but you play hunt and chase with npm versions all the time.

Install using smart versioning

Let’s say you like to install the rush compiler and don’t care about what patch version it has as long as it is the latest. In this case, you can install the rush-stack-compiler using the following command.

npm install @microsoft/rush-stack-compiler-3.3@~0.2.x --save-dev

Now the option –save-exact’ or ‘-E’ has been removed, and instead of specifying a specific version we install the version ‘~0.2.x’. The x at the end means that we don’t care about the patch level as long as it is the latest patched version. The Tilda character in front makes additionally sure the only the latest patch version gets installed.

npm outdates shows that it can be upgraded to the latest patch version

npm outdated shows that the rush-stack-compiler can be upgraded to the latest patch version

So now the picture looks different. Even if we haven’t touched our project in a while since we installed version ‘0.2.7’ we see that there is a newer patched version available. In our case, the version ‘0.2.13’ gets installed because want to have the latest patch. You can even execute npm update to catch up with the latest versions.

The rust-stack-compiler is not outdated anymore

The rust-stack-compiler is not outdated anymore and npm update was successful.

npm outdated does not show that our installed packages are outdated anymore.

To see the installed version the installed you can use the following command:

npm ls @microsoft/rush-stack-compiler-3.3

Returning the following information:A search for the currently installed rush compiler shows the newest version

What else to know about semantic versioning

These are the following rules on how to specify the version in your ‘package.json’ that gives you control over patch releases, minor and major version of packages.

  • Patch releases: 1.0 or 1.0.x or ~1.0.4
  • Minor releases: 1 or 1.x or ^1.0.4
  • Major releases: * or x

Depending on how you specify the version on npm install, you get perfect control over the versions.

I would only recommend using this method for all additional packages that are not part of the core SharePoint framework such as these packages.

  • @microsoft/sp-build-web
  • @microsoft/sp-module-interfaces
  • @microsoft/sp-tslint-rules
  • @microsoft/sp-webpart-workbench
  • @microsoft/sp-build-web
  • @microsoft/sp-module-interfaces
  • @microsoft/sp-tslint-rules
  • @microsoft/sp-webpart-workbench

So basically everything that starts with ‘@microsoft/sp-‘. Some packages already make use of the semantic versioning in the package.json file:

  • “ajv”: “~5.2.2”
  • “gulp”: “~3.9.1”

These update automatically to newer patches. Potentially they could even be changed to the following information:

  • “ajv”: “^5.2.2”
  • “gulp”: “^3.9.1”

The caret, in this case, means that minor version updates are except able to, but there were no newer versions available during writing this blog post.

Caret versioned package in package.json

Caret versioned package in package.json

Final thoughts

For an add-on to SPFx projects and even the rush compiler, in my opinion, it makes absolute sense not to use a fixed version and keep your project up to date automatically rather than freeze into a fixed version. Especially when patched versions fix an internal problem that you might not even are aware of.

A minor version also means that there should be no breaking changes included so this kind of package versioning might work too. In the worst case, you can always download the dependencies to a specific version. I think it the correct installation of NPM packages helps a lot to avoid hunt and chase newer version especially keep them up to date.

Well and finally there is more please check out the “About semantic versioning” by npmjs.org or for yarn on “versions of dependencies“.