npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

npm2rpm

v6.2.0

Published

Convert npm packages to rpm packages

Downloads

205

Readme

npm2rpm

Known Vulnerabilities Code Climate Build Status

npm2rpm - convert npm modules to RPM packages

Usage: npm2rpm [options]

Options:

  -n, --name <name>          NodeJS module name
  -v, --version <version>    module version in X.Y.Z format
  -s, --strategy [strategy]  Strategy to build the npm packages
  -r, --release [release]    RPM's release (default: 1)
  -t, --template [template]  RPM .spec template to use
  -o, --output [directory]   Directory to output files to
  -h, --help                 output usage information

To create npm2rpm/nodejs-webpack.spec:

./bin/npm2rpm.js -n webpack -v 4.20.2

To download the sources you can use spectool:

spectool --get-files nodejs-webpack.spec

How?

To package npm dependencies in RPM, you have 3 strategies:

Packaging 'single' npm modules into rpms. (-s --strategy single)

This is the way most Linux distributions prefer to do it. See the Fedora guidelines about packaging nodejs libraries. The content of this package will contain just the content of the module, without bundled dependencies. It'll have Requires and Provides equal to the same you see in package.json.

It's the way traditional packaging has always worked. However this model conflicts with the way npm modules are used. npm install stores the whole dependency tree for all of your application dependencies. This is a problem, as your application may depend on 'async >= 1.0.0' but your dependencies may depend on 'async ~ 0.2.0'.

At this point you may have noticed you cannot build 2 RPMs for the same dependency and expect both versions to be installed at the same time. This makes it impossible for two applications with different dependency requirements to work, so this strategy of having one module per RPM spec is very impractical.

In practice, a medium-sized web application can easily have hundreds of dependencies (counting different versions of the same dependency) due to how npm install works. Disregard this stratey if you want to package the dependencies for your application or you'll be in trouble :smile:

Packaging npm modules with bundled dependencies (-s --stategy bundle)

I took this idea from njs2rpm. If you still want to package your applications as rpms, and not face dependency conflicts, you may want to go with this.

The main idea is to include the node_modules directory (dependency tree) in every RPM package.

+--------+----------------------+----------------------+-----------------------------+
|  Type  |       RPM name       |      Provides        |          Requires           |
+--------+----------------------+----------------------+-----------------------------+
| Single | nodejs-<name>        | npm(<name>)          | npm(<dep1>)                 |
|        |                      |                      | ...                         |
|        |                      |                      | npm(<depM>)                 |
| Bundle | nodejs-bundle-<name> | npm(<name>)          | (no deps as Requires)       |
|        |                      |                      |                             |
|        |                      | bundled(npm(<dep1>)) |                             |
|        |                      | ...                  |                             |
|        |                      | bundled(npm(<depN>)) |                             |
+--------+----------------------+----------------------+-----------------------------+

This is OK(ish) as you solve the problem of conflicting dependencies by bundling dependencies. Furthermore other applications can depende on your system library by having a Requires: npm(name) However it still seems wrong to put these libraries in your %{nodejs_sitelib} - it's like your installing stuff on the user system but they don't really know about these bundled deps or any security they may have. So I understand why Fedora guidelines discourage this kind of bundling for system packages.

In order to include these bundled dependencies, npm2rpm downloads all dependencies and puts them in the SOURCES folder, and it adds the Provides/Sources for them. It uses npm to install the package, and since it assumes you'll build the package in an offline machine (common security measure), npm2rpm generates a tarball with an npm cache, so that it's able to install it offline. Notice the npm cache has to be generated using the same major version of npm as the one used in the machine where you build the package. e.g: a cache generated with npm 1.3.6 will not work with 2.3.5.

You can circumvent this problem by generating the cache tar manually with all npm versions you want, then put it all in the same tarball. To generate the cache tarball on other npm versions, you can use the script generate_npm_tarball.sh. By default npm2rpm will generate a cache tarball with your default npm version, so you should only generate it manually if you want cache tarballs for multiple npm versions

Putting your node_modules in a separate package

If none of these two options were good for you, you can put your node_modules directory in a tar. Then unpack the module in a location known by your main application, and copy it from there. No other application in your system needs to even know your npm dependencies exist. Check out an example here.

PeerDependencies

On npm versions less than 3.0.0, npm will try to install peerDependencies. Currently npm2rpm does not generate the spec with support for peerDependencies, however, it's easy to do it yourself (for now!).

Start by adding 'BuildRequires' for all peerDependencies (you need to generate these packages too). For example, for babel-loader:

BuildRequires: npm(webpack)
BuildRequires: npm(babel-core)

On your %build section, make symbolic links for these libraries before running npm install:

ln -s %{nodejs_sitelib}/webpack node_modules/webpack
ln -s %{nodejs_sitelib}/babel-core node_modules/babel-core
npm install [email protected] --cache-min Infinity --cache .

That's all you need to include peerDependencies in your packages

License

GPLv3 - see LICENSE

Thanks to njs2rpm(abandoned) and foreman-packaging that provided motivation to make this project.

TODOs:
  • Support peerDependencies with bundled packages