Private path for NPM packages
Summary
Define a FHS-compliant path for NodeJS modules that should not be globally visible, and provide guidance and support for "private" NPM packages shipped via RPM.
Owner
- Name: Jan Staněk
- Email: jstanek@redhat.com
Current status
- Targeted release: Fedora Linux 43
- Last updated: 2025-04-04
- [<link to devel-announce post will be added by Wrangler> Announced]
- [<will be assigned by the Wrangler> Discussion thread]
- FESCo issue: <will be assigned by the Wrangler>
- Tracker bug: <will be assigned by the Wrangler>
- Release notes tracker: <will be assigned by the Wrangler>
Detailed Description
There is an ongoing attempt at de-bundling parts of NodeJS itself; mainly bundled NPM packages that contain pre-build WASM (binary!) blobs in their sources.
With multiple streams (major versions) of NodeJS present in Fedora and the upstream strong recommendation against globally-shared NPM packages, we need to define a place in which NPM packages formerly distributed as part of NodeJS itself can be placed without "polluting" the global NPM search path (/usr/lib/node_modules and the versioned variants).
The proposed new root path is %{_libdir}/nodejs/packages, with the assumed contents:
%{_libdir}/nodejs/packages/sharedfor NPM packages that can be shared between multiple NodeJS major versions. This should be the default path for the unbundled packages unless a stream is identified to need a specific version.%{_libdir}/nodejs/packages/<major_version>for NPM packages that are specifically used by a single NodeJS major version. Reserved for compat-style packages.
Packages installed in these paths are assumed to be used by a non-npm-related loading mechanism; for NodeJS specifically, via the "Shared builtins" mechanism (upstream docs).
Alternative path options
1. %{nodejs_sitelib} / %{_libdir}/node_modules_<major_version>:
- This would make the "Shared builtin" visible for NPM package search as a globally-installed package, which is frowned upon by upstream.
- No explicit support for packages shared between major versions, each unbundled package would need to be built against/installed for each active NodeJS version.
2. %{_libdir}/node/<package>/<version>: The official "global" NPM path (docs).
- This would make the "Shared builtin" visible for NPM package search as a globally-installed package, which is frowned upon by upstream.
sudo npm install --globalwill also use this path; can mess up the RPM expectations.
Feedback
None yet.
Benefit to Fedora
By having downstream-standartized path for "Shared builtins" modules, we can start removing potentially unsafe pre-build WASM (binary) blobs from the NodeJS sources, rebuilding them on our infrastructure from trusted sources.
Accommodating single default shared directory will reduce work necessary for unbundling the packages from several NodeJS major versions at once, while the reservation of version-specific path will allow for compatibility packages where necessary.
Scope
- Proposal owners: Nodejs SRPM macros (redhat-rpm-config package) were extended with macros for the private path(s), so that they are easily usable from the unbundled RPMs. The unbundled RPMs (currently, nodejs-cjs-module-lexer and nodejs-undici) were adjusted to install into the new paths.
- Other developers: Any developers relying on the unbundled RPMs (we are not aware of any yet) will need to voice their need. In that case, compatibility (sub-)package for those components will be provided.
- Policies and guidelines: NodeJS packaging guidelines has to be updated with information about the new macros, their intended use-case, and usage. Can be done after the change is implemented.
- Trademark approval: N/A (not needed for this Change)
- Alignment with the Fedora Strategy: This is exploration/development in Linux distribution space. It attempts to solve problems specific for the distribution space.
Upgrade/compatibility impact
No upgrade impact should be noticeable.
Early Testing (Optional)
Do you require 'QA Blueprint' support? N
How To Test
Package "private" NPM package.
User Experience
Invisible to end-user.
Dependencies
N/A.
Contingency Plan
- Contingency mechanism: Continue/revert to the current state of things, using packages bundled from upstream.
- Contingency deadline: N/A (not a System Wide Change)
- Blocks release? N/A (not a System Wide Change), Yes/No
Documentation
N/A (not a System Wide Change)
