Some node modules are rather small and sometime are dependency of only one package. To avoid having many node modules, qa.debian.org and uscan provides hooks that can be used to simplify maintenance.

This chapter is a guidelines, no a set of rules. If you have any doubt, write a mail to Debian JS Team mailing list.

Some acceptable reasons to embed a node module:

If you have any doubt, write a mail to Debian JS Team mailing list

Adding component version in package version allows uscan to follow upstream changes? This is a security point and must be examined using this point of view. Guidelines to add component version in package version:

Do I have to export embedded modules or not?

As explained after, you can export components or not using Provides: field in debian/control and install it in node path (see below). Some guidelines to choose:

By default, pkg-js-tools will install embedded modules in path/to/main/module/node_modules. You can override this if you want to make the embedded module directly accessible for other packages (required if you "provides" it).

Building a multiple npmjs source package

In this example, we are building node-test package (named test in npmjs.com) including ta and tb npmjs modules.

Step 0: verify that embedded modules don't exist already

To avoid package conflicts and embedded copies:

If component doesn't exist there, insert its (Debian) name in pending embedded modules. Please clean also this list when package has been accepted in unstable.

Step 1: Add/del components

pkg-js-tools way

Simply launch:

$ add-node-component -i ta tb

or

$ add-node-component -gi ta tb

-g options use "group" instead of "ignore" in debian/watch. See pkg-js-tools doc for more.

Then update debian/changelog version. Example:

dch -v 3.1.4+~3.0.2+~3.1.3-1 'Import upstream version 3.1.4+~3.0.2+~3.1.3-1'

To delete a component, launch del-node-component with the same options than add-node-component.

Manual way

Update debian/gbp.conf and debian/watch

git-buildpackage will build embedded sources automatically if both debian/gbp.conf and debian/watch are well configured:

[DEFAULT]
component = [ 'ta', 'tb' ]

version=4

# Prefer source repositories, even if this example uses npm registry
opts="searchmode=plain,pgpmode=none" \
 https://registry.npmjs.org/test \
 https://registry.npmjs.org/test/-/test-(\d[\d\.]*)@ARCHIVE_EXT@ group

opts="searchmode=plain,pgpmode=none,component=ta" \
 https://registry.npmjs.org/ta \
 https://registry.npmjs.org/ta/-/ta-(\d[\d\.]*)@ARCHIVE_EXT@ group

opts="searchmode=plain,pgpmode=none,component=tb" \
 https://registry.npmjs.org/tb \
 https://registry.npmjs.org/tb/-/tb-(\d[\d\.]*)@ARCHIVE_EXT@ group

See uscan manpage for more. Quick explanations:

See node-rollup-plugin-sourcemaps commit as an example.

Download sources

Launch uscan, then gbp import-orig --pristine-tar ../<main>.orig.tar.xz will upload all components even if they are new. The source directory contains now upstream source and one directory per sub module named by their component name:

$ ls -l
debian/
ta/
tb/
index.js
package.json
...

Then update debian/changelog version. Example:

dch -v 3.1.4+~3.0.2+~3.1.3-1 'Import upstream version 3.1.4+~3.0.2+~3.1.3-1'

Example shell script (manual way)

This is an example script used to update gulp. Usage: add-components <component name>

if ! grep $1 debian/gbp.conf; then
  echo "gbp.conf should be updated manually"
  exit 1
fi

echo "Adding module to watch file..."
WATCH_TEMPLATE="
\
opts=\"searchmode=plain,pgpmode=none,component=$1\" \\
https://registry.npmjs.org/$1 \\
https://registry.npmjs.org/$1/-/$1-(1.[\d\.]*)@ARCHIVE_EXT@ ignore"
echo "$WATCH_TEMPLATE" >>debian/watch

echo "Adding module to install file..."
echo "$1 usr/lib/nodejs/gulp/node_modules/" >>debian/install

echo "Downloading source tarballs..."
uscan -dd

echo "Creating source package..."
dpkg-source -b .

echo "Removing patches applied..."
quilt pop -a && rm -rf .pc

echo "Committing modified files..."
git commit debian/gbp.conf  debian/install debian/watch -m "Add $1"

echo "Importing dsc to git..."
gbp import-dsc --pristine-tar ../node-gulp_4.0.2-1.dsc

echo "Removing debian tag..."
git tag -d debian/4.0.2-1

Step 2: configure other debian/* files

debian/control

To avoid multiple embedding, you must share sub components with other. This is done by adding a "Provides:" field in debian/control: Note what for smooth upgrade improvement main package is called node-debbundle-foo (allow simpler merge/split if needed)

...
Package: node-debbundle-foo
Depends: ${misc:Depends},
         nodejs,
         pkg-js-tools (>= 0.8.10)
Provides:
   node-foo (=1.0.0)
   node-ta (= 1.2.3),
   node-tb (= 0.3.4)
...

debian/copyright

Of course, update debian/copyright with components copyrights.

debian/rules

Just to add --with nodejs here, it will add needed symlinks. If a component needs another one during build, use debian/nodejs/component_links (see pkg-js-tools doc)

%:
    dh $@ --with nodejs

debian/install

pkg-js-tools will automatically install all components in /usr/share/nodejs/<foo>/node_modules (or /usr/lib/<arch>/nodejs/<foo>/node_modules). If this is not the wanted place, use debian/nodejs/<component>/install as described in pkg-js-tools documentation. So remove debian/install unless you're building a multiple binaries package (see pkg-js-tools doc).

Other files

Check if it is useful or not to export component README, changelog,...

autopkgtest

Nothing special here except that you can build a test for each component if main component test seems not enough. It is important to write tests that really require every embedded component, so autopkgtest will prove that install is good.

pkg-js-tools can do it for you: you just have to write a debian/tests/pkg-js/test file with the test to launch (see package.json: "scripts":"test"). The test is automatically launched during build and during autopkgtest. You need to add "Testsuite: autopkgtest-pkg-nodejs" in your debian/control.

The end

When build is OK, of course verify using debc that install looks good (package are really usable.

NB: if you need to build something in a component, pkg-js-tools (>= 0.9.4) provides an easy way to do it: write your build commands in debian/nodejs/<component>/build instead of writing the build in an override_dh_auto_build. You can also do the same (debian/nodejs/build) for the main package.

Using git subtree to track multiple upstream (optional)

git subtree could be used to track multiple upstream, and allow easier cherry picking. Let suppose that you want to package node-acorn with subpackage node-acorn-node.

you should first add the remote acorn and remote acorn-node

git remote add upstream-acorn https://github.com/acornjs/acorn
git remote add upstream-acorn-bigint https://github.com/acornjs/acorn-bigint
git remote add upstream-acorn-import-meta https://github.com/acornjs/acorn-import-meta/
git remote add upstream-acorn-node https://github.com/browserify/acorn-node

Fetch all

git fetch --all

If not done create a fake upstream branch for main package

git checkout gitidofupstreamcorn
git checkout -b upstreamdebian