diff --git a/README.md b/README.md index 9c45063..f0c2a1a 100644 --- a/README.md +++ b/README.md @@ -135,3 +135,84 @@ popd ## Submit built packages to Bodhi Follow the usual processes for stable/branched releases to submit builds for testing. + + +# How to bundle nodejs libraries in Fedora + +The upstream Node.js stance on +[global library packages](https://nodejs.org/en/blog/npm/npm-1-0-global-vs-local-installation/) +is that they are ".. best avoided if not needed." In Fedora, we take the same +stance with our nodejs packages. You can provide a package that uses nodejs, +but you should bundle all the nodejs libraries that are needed. + +We are providing a sample spec file and bundling script here. +For more detailed packaging information go to the +[Fedora Node.js Packaging Guildelines](https://docs.fedoraproject.org/en-US/packaging-guidelines/Node.js/) + +## Bundling Script + +``` +nodejs-packaging-bundler [version] +``` + +nodejs-packaging-bundler is it's own package, nodejs-packaging-bundler and must be installed before use. +nodejs-packaging-bundler gets the latest npm version available, if no version is given. +It produces four files and puts them in ${HOME}/rpmbuild/SOURCES + + * -.tgz - This is the tarball from npm.org + * --nm-prod.tgz - This is the tarball that contains all the bundled nodejs modules needs to run + * --nm-dev.tgz - This is the tarball that contains all the bundled nodejs modules needs to test + * --bundled-licenses.txt - This lists the bundled licenses in --nm-prod.tgz + +## Sample Spec File + +``` +%global npm_name my_nodejs_application +... +License: and and +... +Source0: http://registry.npmjs.org/%{npm_name}/-/%{npm_name}-%{version}.tgz +Source1: %{npm_name}-%{version}-nm-prod.tgz +Source2: %{npm_name}-%{version}-nm-dev.tgz +Source3: %{npm_name}-%{version}-bundled-licenses.txt +... +BuildRequires: nodejs-devel +... +%prep +%setup -q -n package +cp %{SOURCE3} . +... +%build +# Setup bundled node modules +tar xfz %{SOURCE1} +mkdir -p node_modules +pushd node_modules +ln -s ../node_modules_prod/* . +ln -s ../node_modules_prod/.bin . +popd +... +%install +mkdir -p %{buildroot}%{nodejs_sitelib}/%{npm_name} +cp -pr index.js lib package.json %{buildroot}%{nodejs_sitelib}/%{npm_name} +# Copy over bundled nodejs modules +cp -pr node_modules node_modules_prod %{buildroot}%{nodejs_sitelib}/%{npm_name} +... +%check +%nodejs_symlink_deps --check +# Setup bundled dev node_modules for testing +tar xfz %{SOURCE2} +pushd node_modules +ln -s ../node_modules_dev/* . +popd +pushd node_modules/.bin +ln -s ../../node_modules_dev/.bin/* . +popd +# Example test run using the binary in ./node_modules/.bin/ +./node_modules/.bin/vows --spec --isolate +... +%files +%doc HISTORY.md +%license LICENSE.md %{npm_name}-%{version}-bundled-licenses.txt +%{nodejs_sitelib}/%{npm_name} +``` + diff --git a/nodejs-packaging-bundler b/nodejs-packaging-bundler new file mode 100755 index 0000000..18be72b --- /dev/null +++ b/nodejs-packaging-bundler @@ -0,0 +1,82 @@ +#!/bin/bash +OUTPUT_DIR="${HOME}/rpmbuild/SOURCES" + +usage() { + echo "Usage `basename $0` [version] " >&2 + echo >&2 + echo " Given a npm module name, and optionally a version," >&2 + echo " download the npm, the prod and dev dependencies," >&2 + echo " each in their own tarball." >&2 + echo " Also finds licenses prod dependencies." >&2 + echo " All three tarballs and license list are copied to ${OUTPUT_DIR}" >&2 + echo >&2 + exit 1 +} + +if ! [ -f /usr/bin/npm ]; then + echo >&2 + echo "`basename $0` requires npm to run" >&2 + echo >&2 + echo "Run the following to fix this" >&2 + echo " sudo dnf install npm" >&2 + echo >&2 + exit 2 +fi + +if [ $# -lt 1 ]; then + usage +else + case $1 in + -h | --help ) + usage + ;; + * ) + PACKAGE="$1" + ;; + esac +fi + +if [ $# -ge 2 ]; then + VERSION="$2" +else + VERSION="$(npm view ${PACKAGE} version)" +fi + +TMP_DIR=$(mktemp -d -t ci-XXXXXXXXXX) +mkdir -p ${OUTPUT_DIR} +mkdir -p ${TMP_DIR} +pushd ${TMP_DIR} +npm pack ${PACKAGE} +tar xfz *.tgz +cd package +echo " Downloading prod dependencies" +npm install --no-optional --only=prod +if [ $? -ge 1 ] ; then + echo " ERROR WILL ROBINSON" + rm -rf node_modules +else + echo " Successful prod dependences download" + mv node_modules/ node_modules_prod +fi +echo "LICENSES IN BUNDLE:" +find . -name "package.json" -exec jq .license {} \; >> ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt +find . -name "package.json" -exec jq '.licenses[] .type' {} \; >> ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt 2>/dev/null +sort -u -o ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt ${TMP_DIR}/${PACKAGE}-${VERSION}-bundled-licenses.txt +echo " Downloading dev dependencies" +npm install --no-optional --only=dev +if [ $? -ge 1 ] ; then + echo " ERROR WILL ROBINSON" +else + echo " Successful dev dependences download" + mv node_modules/ node_modules_dev +fi +if [ -d node_modules_prod ] ; then + tar cfz ../${PACKAGE}-${VERSION}-nm-prod.tgz node_modules_prod +fi +if [ -d node_modules_dev ] ; then + tar cfz ../${PACKAGE}-${VERSION}-nm-dev.tgz node_modules_dev +fi +cd .. +cp -v ${PACKAGE}-${VERSION}* $HOME/rpmbuild/SOURCES +popd > /dev/null +rm -rf ${TMP_DIR} diff --git a/nodejs-packaging.spec b/nodejs-packaging.spec index 1292b9c..62de0ca 100644 --- a/nodejs-packaging.spec +++ b/nodejs-packaging.spec @@ -1,7 +1,7 @@ %global macrosdir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) Name: nodejs-packaging -Version: 2020.09 +Version: 2021.01 Release: 1%{?dist} Summary: RPM Macros and Utilities for Node.js Packaging BuildArch: noarch @@ -19,6 +19,7 @@ Source0007: nodejs-symlink-deps Source0008: nodejs.attr Source0009: nodejs.prov Source0010: nodejs.req +Source0011: nodejs-packaging-bundler # Created with `tar cfz test.tar.gz test` Source0101: test.tar.gz @@ -31,6 +32,17 @@ Requires: redhat-rpm-config This package contains RPM macros and other utilities useful for packaging Node.js modules and applications in RPM-based distributions. +%package bundler +Summary: Bundle a node.js application dependencies +Requires: npm +Requires: coreutils, findutils, jq + +%description bundler +nodejs-packaging-bundler bundles a node.js application node_module dependencies +It gathers the application tarball. +It generates a runtime (prod) tarball with runtime node_module dependencies +It generates a testing (dev) tarball with node_module dependencies for testing +It generates a bundled licence file that gets the licenses in the runtime dependency tarball %prep pushd %{_topdir}/BUILD @@ -52,6 +64,7 @@ install -pm0755 nodejs-symlink-deps %{buildroot}%{_rpmconfigdir}/nodejs-symlink- install -pm0755 nodejs-fixdep %{buildroot}%{_rpmconfigdir}/nodejs-fixdep install -pm0755 nodejs-setversion %{buildroot}%{_rpmconfigdir}/nodejs-setversion install -Dpm0644 multiver_modules %{buildroot}%{_datadir}/node/multiver_modules +install -Dpm0755 nodejs-packaging-bundler %{buildroot}%{_bindir}/nodejs-packaging-bundler %check @@ -65,8 +78,14 @@ install -Dpm0644 multiver_modules %{buildroot}%{_datadir}/node/multiver_modules %{_rpmconfigdir}/nodejs* %{_datadir}/node/multiver_modules +%files bundler +%{_bindir}/nodejs-packaging-bundler + %changelog +* Wed Jan 06 2021 Troy Dawson - 2021.01 +- Add nodejs-packaging-bundler and update README.md + * Fri Sep 18 2020 Stephen Gallagher - 2020.09-1 - Move to dist-git as the upstream