Project versioning as we used to know it was not a big challenge. Not as long as you only used Visual Studio.
The thing is that assigning a proper version of your SharePoint Framework project is more tricky than simply apply a single version to it. There are more than one version of your project, that doesn’t match and have different purposes.
Visual Studio project version
Visual Studio projects use a version number for each project that contains four digits. This kind of is available everywhere in the Microsoft Universe. Every SharePoint project in the past used this version.
The version contains of four numbers and follows the pattern Major, Minor, Build and the last digit is the revision number.
When you upload the output of a SharePoint Framework project this the app file need to contain a valid version number. The lowest possible version is ‘1.0.0.0’. If a version number below the first major build will be used. SharePoint automatically uses the version ‘1.0.0.0’. No matter if you have specified the version ‘0.9.0.0’.
NodeJS project version
When you create a new project using the yeoman generator you get in the root folder, the ‘package.json’. This file contains another version number that is incompatible with version number used in Visual Studio Projects.
The concept to assign version numbers is called semantic versioning or short ‘semver’.
A valid, semantic version number only contains three mandatory parts. The major, minor and the patch number instead of ‘Build’. Optional, additional labels can be assigned to the version number delimited by a dash. Common values for labels are ‘alpha’, ‘beta’, ‘rc’ for release candidates. Sounds good, because it’s less cryptic than the Microsoft version.
SPFX versioning issue
In fact, any SharePoint Framework project has two different kinds of versions. The more project oriented version number is stored in the ‘package.json’. The web part related is stored in the ‘package-solution.json’ inside the config folder.
Both are valid versions of your project, but they are not in sync and needs to be updated individually. For SharePoint you can update the package-solution file. For the overall project you update the ‘package.json’ in the root folder.
Sooner or later you will lose track of your versions and it will be hard to decide which the correct one is.
Tool support for npm / NodeJS versioning
The node package manager is not only capable to install node modules. It helps you to set a proper version in your ‘package.json’. To update the version you simply need to execute the following command.
npm version <major|minor|patch>
So when you like to increment the major version simply execute ‘npm version major’, use minor instead of major to update to a minor version. In case you like to patch the web part simply specify ‘npm version patch’.
Voilá. The version in the ‘package.json’ has been updated.
Sync npm version with your web part version
Currently there is no tooling support available that allows you to update the version of your web part solution file. You can update the version number manually by editing the ‘package-solution.json’.
Updating this version is not something I like to do all the time. The question is, is there a better way to do this?
Lets say I like to use the tool driven project version of my main project directly in my web part code too.
To solve this issue only a simple gulp task is required. There is one last thing we need to manage. The incompatible version numbers.
Create matching version numbers
As mentioned previously, we need to find a way to make both version numbers matching. So we need to assign the three parts of the npm package version to the SharePoint solution version number.
To create a proper package solution version four digits are needed, but npm contains only of three individual digits.
Let me give you an example. The current overall project version is set to ‘1.9.1-beta’. Now the only thing that needs to be done is to remove the label from the version number. The delimiter to identify the label is a simple dash. So we split the version string and use only the first part.
So we get a new partial version number ‘1.9.1’. The last thing that needs to be done is to add the string ‘.0’ to the partial version number. This way we get the version ‘1.9.1.0’, a valid web part app version of SharePoint.
From a Microsoft version perspective, we lose the last part, the revision number. I think this loss is bearable.
Gulp task to sync versions
The easiest way to implement the version sync is to write a custom gulp task. The first thing that needs to be done is to read both configuration files. Then get the version from the ‘package.json’, create a proper new matching version and write this new version number to the configuration file stored in the ‘package-solution.json’ file.
'use strict'; const gulp = require('gulp'); const build = require('@microsoft/sp-build-web'); build.initialize(gulp); gulp.task('version-sync', function () { // import gulp utilits to write error messages const gutil = require('gulp-util'); // import file system utilities form nodeJS const fs = require('fs'); // read package.json var pkgConfig = require('./package.json'); // read configuration of web part solution file var pkgSolution = require('./config/package-solution.json'); // log old version gutil.log('Old Version:\t' + pkgSolution.solution.version); // Generate new MS compliant version number var newVersionNumber = pkgConfig.version.split('-')[0] + '.0'; // assign newly generated version number to web part version pkgSolution.solution.version = newVersionNumber; // log new version gutil.log('New Version:\t' + pkgSolution.solution.version); // write changed package-solution file fs.writeFile('./config/package-solution.json', JSON.stringify(pkgSolution, null, 4)); });
Now only the version of the npm package needs to be updated through ‘npm version’. After the version has been changed simply execute ‘gulp version-sync’.
Sync version automatically
Running the gulp task manually is nice, but there is a better way to do this. Through the help of a simple npm script.
Whenever you update your version two events will be raised. ‘preversion’ will be raised before the version will be updated. ‘postversion’ is the right event to use. This will be raised after the version have been changed. Simply add a new script to your ‘package.json’. Name the script ‘postversion’ and define the execution with ‘gulp version-sync’.
... "scripts": { "build": "gulp bundle", "clean": "gulp nuke", "test": "gulp test", "postversion": "gulp version-sync" } ...
Finally, lets put this to test. Simply execute ‘npm version’. Now the version in the ‘package.json’ will be updated first. The version sync task will be automatically called and finally we get a version corresponding to our ‘package-solution. json’.
SPFx versioning issue solved?
I would say yes. At least it helps to manage the centralized version. I know it is just an intermediate fix to make the different version schematics matching.
It would be great if SharePoint would support semantic version in addition but by now we need to use this workaround.
What do you think? Will you use this centralized version or will you just update one or the other version identifier.
Would the Solution version nr (semver) also be useful to write to (all) the webpart manifest files?
// process webpart manifests too
gulp.src(‘./src/webparts/*/*.manifest.json’).pipe(tap(function(file,f){
// load the webpart manifest
var wpManifest = require(file.path);
// update the version nr of the webpart manifest
wpManifest.version = pkgConfig.version;
// log the new version
gutil.log(‘New Manifest Version ‘ + wpManifest.alias + ‘ t’ +pkgConfig.version);
// write changed webpart manifest file
fs.writeFile(file.path, JSON.stringify(wpManifest, null, 4));
}));
Yes absolutely. This should be in sync with the version number too but I currently spared this part out in the blog post.
Thanx for providing a solution for this problem here on my blog post. I planned to do a blog post on this challange too. 😉
/Stefan
I put it online for you and your readers, thanks for the great content! https://stefvanhooijdonk.nl/2016/11/22/how-to-version-new-sharepoint-framework-projects-addition/
[…] How to version new SharePoint Framework projects […]