Npm is an incredible tool, but the way it manages ranged versions can present some challenges. If you're new to npm, or haven't given much thought to why it works the way it does take a look at the following article by Alexis King.
Ionic Appflow builds:
When you build your app in Ionic Appflow all dependencies are restored on the spot from your project configuration. The version specs present in package.json determine which version will be retrieved. If you specify a version range for a module be aware that you may see changes in behavior when there's an update. This is how a formerly good build can fail when run at a later date. This can also be a factor when behavior differs from local builds.
Versions in npm follow the semver scheme.
- The first segment is the major version. Major versions should be used for significant changes that are not backwards compatible, or "breaking changes".
- The second segment is the minor version. Minor versions are incremented for releases that add features but are still backwards compatible.
- The last segment is the patch version. The patch version is used for bug fixes and small adjustments.
It's important to note that this is how semver is intended to be used. Not every module will follow these guidelines. It's certainly possible to release a breaking change under a new patch version deliberately, or unintentionally.
You can allow for version ranges using the following characters.
- * (asterisk) latest major version x.x.x
- ^ (carat) latest minor version 1.x.x
- ~ (tilde) latest patch version 1.1.x
A version spec can be passed in with the npm install command or the cordova plugin add command.
npm install @myscope/mylib@^1.3.4
cordova plugin add my-cordova-plugin@^5.4.0
The spec is then included in your configuration file.
In the examples shown above the version spec will allow for the latest 5.x.x release of my-cordova-plugin and the latest 1.x.x release of @myscope/mylib. You can test a version spec against any module in npm using the npm semver calculator.
Specifying an explicit version:
By default npm will include the ^ (carat) when adding a module to package.json. It's sometimes necessary to set a specific version for a module without a range. This can be managed when the module or plugin is installed using the --save-exact or -E flag.
npm install @firstname.lastname@example.org --save-exact
cordova plugin add email@example.com --save-exact
This is helpful when installing npm modules or plugins directly, but it isn't possible when child dependencies are installed. You can override the npm default carat on a per project basis by including an .npmrc file in the root of the app with the following contents.
This is helpful if the range on a child dependency is causing problems but can become difficult to maintain. It's usually preferable to allow the ranges specified for child dependencies in a module whenever possible.
Managing explicit versions:
As a best practice you should monitor for critical updates to any modules, especially those with an explicit version spec. The npm outdated command will generate a list of project modules and the current, wanted, and latest versions.