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.
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-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.
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 @email@example.com --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.
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 @firstname.lastname@example.org --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.
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.
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:
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.
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.
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.