When I create an npm package, sometimes it would face the need to backward old dependency package version.
If the new version has new api, I may write the code in this pattern:
import pkg from 'some-pkg';
const isNewVersion = pkg.newVersionApi !== 'undefined';
if (isNewversion) {
pkg.newVersionApi();
} else {
pkg.oldVersionApi(); // backward compatible api
}
And with this pattern, when I want to write the test, I only can test the installed version
code. The other version's code can't be tested.
For real example, in React v15 and v16, React v16 has new API Portal. Before Portal release, v15 has unstable_renderSubtreeIntoContainer
api to realize similar feature.
So the code for React would be like:
import ReactDOM from 'react-dom';
const isV16 = ReactDOM.createPortal !== 'undefined';
if (isV16) {
ReactDOM.createPortal(...);
} else {
ReactDOM.unstable_renderSubtreeIntoContainer(...);
}
So I want to ask is there any method to test with different dependency version
?
Currently, one method I think of is to install the other version again and test it. But it only can do on local. It can't work on ci and it can't count in coverage together.
I think that is not only for react test. It may face on node.js test. Any suggestion can be discussed.
Updated
This question maybe is related to install two versions dependency
in npm. But I know currently installing two versions dependency is not workable.
If you need to use a different version of npm for each project, there are a number of possible solutions. Probably the lightest-weight version is to use npx . A semi-common use-case for this can be projects that use lock-file v1 and another that uses lock-file v2. v2 was introduced in npm v7.
With npm or yarn, you can install a package under a custom alias. This enables you to install multiple versions of a package in the same project. Read the documentation on aliasing with npm here and yarn here.
The good news is that you can have it done directly via NPM! What can be done in this case is an idea called "package alias". So you can have multiple versions of the same package running in your app and you can work on the upgrades mitigating possible issues.
Multiple package. json files give you a lot of flexibility to run different/incompatible versions of dependencies. As a practical example, on one of the projects that I work on we have 2 package. json files, one for the main application code and then another one for our BDD tests.
Here is a might be solution, not sure it will work as you expect. But, you will have a direction to move forward.
package.json
{
"name": "express-demo",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"dependencies": {
"cookie-parser": "~1.4.3",
"debug": "~2.6.3",
"express": "~4.15.2",
"jade": "~1.11.0",
"morgan": "~1.8.1",
"serve-favicon": "~2.4.2",
"webpack": "^3.8.1",
"webpack-dev-middleware": "^1.12.0",
"webpack-hot-middleware": "^2.20.0"
},
"customDependecies": {
"body-parser": [
"",
"1.18.1",
"1.18.0"
]
}
}
Note in above package.json
file, I have added a new key customDependecies
which I will use for installing multiple dependencies. Here I am using body-parser
package for demo. Next you need file, that can read this key
and install the deps.
install-deps.js
const {spawnSync} = require('child_process');
const fs = require('fs');
const customDependencies = require('./package.json').customDependecies;
spawnSync('mkdir', ['./node_modules/.tmp']);
for (var dependency in customDependencies) {
customDependencies[dependency].forEach((version) => {
console.log(`Installing ${dependency}@${version}`);
if (version) {
spawnSync('npm', ['install', `${dependency}@${version}`]);
spawnSync('mv', [`./node_modules/${dependency}`, `./node_modules/.tmp/${dependency}@${version}`]);
} else {
spawnSync('npm', ['install', `${dependency}`]);
spawnSync('mv', [`./node_modules/${dependency}`, `./node_modules/.tmp/${dependency}`]);
}
});
customDependencies[dependency].forEach((version) => {
console.log(`Moving ${dependency}@${version}`);
if (version) {
spawnSync('mv', [`./node_modules/.tmp/${dependency}@${version}`, `./node_modules/${dependency}@${version}`]);
} else {
spawnSync('mv', [`./node_modules/.tmp/${dependency}`, `./node_modules/${dependency}`]);
}
});
}
spawnSync('rm', ['-rf', './node_modules/.tmp']);
console.log(`Installing Deps finished.`);
Here, I am installing deps one by one in tmp
folder and once installed, I am moving them to ./node_modules
folder.
Once, everything is installed, you can check the versions like below
index.js
var bodyParser = require('body-parser/package.json');
var bodyParser1181 = require('[email protected]/package.json');
var bodyParser1182 = require('[email protected]/package.json');
console.log(bodyParser.version);
console.log(bodyParser1181.version);
console.log(bodyParser1182.version);
Hope, this will serve your purpose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With