Is it possible to rebuild all built content in a node_modules directory? #199880
Replies: 7 comments 5 replies
This comment was marked as low quality.
This comment was marked as low quality.
-
|
Your observations are consistent with how npm rebuild works. npm rebuild does not generally inspect the contents of a package and determine whether generated artifacts are missing. Instead, it primarily re-runs the lifecycle scripts (install, preinstall, postinstall, etc.) for packages that npm considers rebuildable, particularly native addons. As a result, simply deleting a generated binary, .node file, or .wasm file from an existing node_modules tree does not necessarily cause npm rebuild to regenerate it. If the package's install scripts are not re-executed, npm may report success without recreating the missing artifacts. For a fully reproducible offline build, it may be more reliable to: Download and cache all package sources and tarballs online. One challenge is that npm itself does not maintain a complete inventory of generated artifacts (native binaries, Wasm files, transpiled output, etc.), so there is no built-in command that says "rebuild everything that was previously generated and later removed." If Fedora's requirements are strict about rebuilding all generated content from source, the most robust approach may be to reconstruct the dependency tree from source tarballs and execute the package lifecycle scripts in the offline build environment rather than relying on npm rebuild against a modified node_modules directory. |
Beta Was this translation helpful? Give feedback.
This comment was marked as low quality.
This comment was marked as low quality.
-
|
The new detail about the In the symlinked tree, npm is seeing dependencies resolved from The npm lifecycle model treats local/file/link dependencies differently from packages installed from published tarballs. For published packages, the expectation is generally that the package already contains its build artifacts. For local or linked packages, npm often runs The log snippet showing: npm info run @eslint/eslintrc@2.1.4 prepare appears consistent with that interpretation. If that's correct, npm rebuild may not be deciding based on missing artifacts at all. Instead, it may be deciding based on package type (registry package vs file/link package) and the lifecycle hooks associated with that type. One thing that might help confirm this would be comparing:
between the registry-installed tree and the symlinked tree, specifically looking for link/file dependency flags. My guess is that the symlinked layout is causing Arborist to classify the packages differently, which in turn makes |
Beta Was this translation helpful? Give feedback.
-
|
The latest findings seem to support the idea that npm is treating the symlinked tree as a collection of local/file dependencies rather than registry-installed packages. The fact that One thing I'd be curious about is whether the same behavior can be reproduced with a minimal test case:
If the behavior differs solely based on the That may not solve the broader "rebuild everything from source" problem, but it could explain why the current process behaves differently from a standard installed tree. |
Beta Was this translation helpful? Give feedback.
-
|
A few things that might help based on similar offline builds I've dealt with:
npm rebuild alone isnt always reliable — some packages expect a full npm install to run postinstall, so those need special handling in offline setups. |
Beta Was this translation helpful? Give feedback.
-
|
Hey! We're packaging a Node.js app for Fedora, which requires building fully offline from source. Our plan is to run npm install online, strip pre-built binaries/Wasm, archive node_modules, then rebuild everything offline. Rebuilding offline — npm rebuild does nothing after we remove binaries, but works fine if we recreate node_modules with symlinks. Not sure what triggers npm to actually rebuild a module. Any guidance on best practices would be appreciated. Thanks! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
🏷️ Discussion Type
Question
Body
I'm trying to work out a build process for Node.js software in Fedora. Fedora requires, among other things, that all software is built from source, and that all software is built offline.
I think that we would like to see a process that is more or less:
Online:
Offline build:
I am unclear on how to do 2 and 3 in the offline build.
If I run "npm install" and remove native binaries and Wasm, and then run "npm rebuild", npm will spin for a few seconds and then tell me that it is done. However, none of the generated files have been re-built. I don't see any evidence that npm is trying to run a build in the node_modules collection. But if I create a new node_modules and populate it with symlinks to the same collection of node modules and then run "npm rebuild", npm does appear to try to run a "build" process for each node module. I don't understand how npm is determining whether or not to try to build each module.
Naturally, some packages such as those that provide tsc, or rollup, or other build tools will need to be packaged and installed system wide in order to "rebuild" a node_modules collection that doesn't contain any native binaries. But assuming we build those, we still need to be able to tell npm to rebuild a module collection from which some content has been removed.
Once that's sorted, we also need to be able to "install" only the runtime dependencies into a directory that we'll archive for distribution. I think we might be able to "prune" the node_modules directory of devDependencies and install what is left, but I would appreciate any guidance on best practice or generally simpler processes.
Thank you
Beta Was this translation helpful? Give feedback.
All reactions