Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test two different npm package versions at the same time

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.

like image 410
Chen-Tai Avatar asked Nov 22 '17 04:11

Chen-Tai


People also ask

How do I use two npm versions?

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.

Can I install two versions of npm package?

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.

Can I have multiple versions of npm?

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.

Can you have two package Jsons?

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.


1 Answers

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.

like image 174
Vipin Kumar Avatar answered Nov 14 '22 23:11

Vipin Kumar