Test two different npm package versions at the same time

Viewed 2235

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.

4 Answers

In addition to the other suggestions, you can try the approach described at Testing multiple versions of a module dependency.

Here's an example of using this approach to test against multiple webpack versions:

npm install --save-dev module-alias
npm install --save-dev webpack-v4@npm:webpack@4.46.0
npm install --save-dev webpack-v5@npm:webpack@5.45.1

The module-alias package handles the magic of switching between package versions while still supporting normal require('webpack') (or whatever your module is) calls.

The other installs will create two versions of your dependency, each with a distinct directory name within your local node_modules/.

Then, within your test code, you can set up the dependency alias via:

const path = require('path');
require('module-alias').addAlias(
  'webpack',
  path.resolve('node_modules', 'webpack-v4'),
);

// require('webpack') will now pull in webpack-v4

You'd do the same thing for 'webpack-v5' in a different test harness.

If any of your sub-dependencies have a hardcoded require('webpack') anywhere in their own code, this will ensure that they also pull in the correct webpack version.

Related