Handling Multiple Version Scenarios

T.C. Hollingsworth tchollingsworth at gmail.com
Wed Jun 5 01:56:24 UTC 2013

The "inherits" module has a new breaking version out, and some modules
are now using both versions.  Jamie and I ran into something like this
with uglify-js, and we just hacked around it for then, but doing that
for this situation would probably take longer than just finding a nice
way to make this easier generally, so lets do that.  ;-)

Here's what I have in mind:

Packages in this situation should install in version-specific
directories under %{nodejs_sitelib}, e.g.:
uglify-js (2.x) -> %{nodejs_sitelib}/uglify-js at 2
uglify-js1 (1.x) -> %{nodejs_sitelib}/uglify-js at 1

The @ sign is special to npm.  To get uglify-js 1 instead of 2 with
npm you'd run `npm install uglify-js at 1`, so by using it here that
means you can also `npm link uglify-js at 1` to bring in the RPM version.
 It also prevents clashes with module names that happen to contain
numbers, and opens the door to patches to npm in the future to be
smarter here.  (e.g. so even `npm link uglify-js at 1.3` will do the
right thing as `npm install uglify-js at 1.3` does.)

The main uglify-js package in this example would also contain a
%{nodejs_sitelib}/uglify-js -> uglify-js at 2 symlink so `npm link
uglify-js` continues to work.

Now that we have a way to install them, we need a way to tell
%nodejs_symlink_deps about these special modules.  There are two ways
I can think of:

1.) Make it check %{nodejs_sitelib} at build time for the existence of
these name at version directories.  This requires that every package that
have dependencies experiencing this issue to BuildRequire those
dependencies, but doesn't require keeping track of these centrally as
with 2.

2.) Just keep a text file in "nodejs-packaging" with a list of these
special modules.  That means updating nodejs-packaging and keeping
track of these special modules, but nothing special for package
maintainers unless they need to BuildRequire them for %check.  This
text file would just be a simple newline-separated list of the npm
names of the affected modules.

There's also technically 3.) Just ship everything in versioned
directories so we don't have to worry about it.  But that adds a bunch
of complexity for a 1% case and requires changing every package, so I
think that one is a no go.

I'm leaning towards 2 because that prevents packagers from having to
deal with any of this in most cases.  The only one where they'd need
to be aware of it is for BuildRequires when you need the right version
of the module, in which case they'd just have to make sure they drag
in the right version, preferably with something like:
BuildRequires: npm(uglify-js) < 2

Note that the right RPM is already brought in properly regardless
thanks to the "npm(foo)" virtual provides, so that part of the problem
is already solved.  The RPM name will remain irrelevant, but should
follow the standard Fedora policy for this regardless (which seems to
be just appending the major part of the version to the name).

Also, I'm only worrying about major versions here, because all npm
modules are supposed to follow the semantic versioning spec [1] which
requires a major version bump for this sort of thing to happen anyway,
so I don't see the point in overengineering this at this time.

I'm curious if anyone has any other suggestions or a recommendation
here.  Thanks!


[1] http://semver.org/

More information about the nodejs mailing list