Repository navigation
Conversation
…ions The `local-address` definition built its list of allowed values with `os.networkInterfaces()` when the definitions module loaded, so every npm command enumerated the machine's network interfaces at start-up. The list is only needed to validate a `local-address` value. - `local-address`'s `type` is now a memoized getter, with `hint` and `usage` given so that `Definition` does not read it to derive them - `Definition` copies property descriptors, so a getter stays a getter - `getTypesFromDefinitions` keeps an accessor type as an accessor; nopt only reads the types of keys that are set - `bin/npx-cli.js` skips accessor types when it collects boolean switches, so npx does not compute the list either Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related: #10084 (Windows shims start node once per call) and #10096
(arborist and pacote on first use). Each removes a different part of npm's start-up cost; they
touch different files and the savings add up.
Summary
@npmcli/config/lib/definitions/definitions.jsbuilds the allowed values oflocal-addressatmodule load:
So every npm command,
npm --versionincluded, enumerates the machine's network interfaces beforeit does anything else. On Windows,
os.networkInterfaces()goes throughGetAdaptersAddressesandtakes about 7.5 ms on the test machine; it grows with VPN and virtual adapters. The list is needed
only when a
local-addressvalue is validated, which almost no command does.bin/npx-cli.jsalso reads every definition's
typeto find boolean switches, sonpxbuilds the list too.This PR:
definitions.js:local-address'stypebecomes a getter that builds the list on firstread and memoizes it.
hintandusageare given explicitly, soDefinitiondoes not readtypeto derive them.definition.js: the constructor copies property descriptors instead of usingObject.assign, so a getter stays a getter. For data properties the two are the same.index.js,getTypesFromDefinitions: a definition whosetypeis an accessor becomes anaccessor in
typestoo. nopt readstypes[key]only for keys present in argv, env or npmrc,so the list is built only when
local-addressis actually set.bin/npx-cli.js: skips accessor types when it collects boolean switches. A lazilycomputed type is a list of values, never a switch. It uses no optional chaining, because the
bin scripts must parse on old Node.
os.networkInterfaces()calls per command go from 1 to 0 fornpm --version,npm run <script>and
npx <bin>.Numbers
npm packoflatest(b317f16), against the same tarball with this commit;with its 95% CI.
npm --version, Dev Drivenpm --version, system drivenpm run noop(node -e 0), Dev Drivenpm run noop, system driveA second 60-pass run, in a clean user environment on a quieter machine, agrees:
npm --versionsaves 7.5 ms (6.7–8.6) on the Dev Drive and 10.4 ms (7.3–11.9) on the system drive;
npm run noop,5.0 ms (2.7–8.1) and 7.6 ms (6.2–9.8).
npx --no-install tsc --version(about 485 ms) is too noisy to resolve 7 ms in 40 passes: 3.0(−7.3–19.0). A hook on
os.networkInterfaces()shows the call gone there too.The change was also tested on Linux: the call count goes from 1 to 0 and nothing regresses.
Behaviour
npm --version;npm config get local-addresswith a valid--local-address, an invalid one (the samewarning and
null), and one fromnpm_config_local_address;npm config ls -l.definitions['local-address'].usage. It was built from the machine's ownaddresses (
--local-address <…|…>) and is shown nowhere: no command listslocal-addressamongits params, and the docs use
typeDescription("IP Address"). It is now--local-address <local-address>.Tests
New tests, each failing without its change:
workspaces/config/test/definitions/definitions.js: the interfaces are not listed when thedefinitions load, nor by reading
hint/usage. They are listed once on the firsttyperead.workspaces/config/test/index.js:getTypesFromDefinitionskeeps an accessor type lazy. AConfigdoes not read it when the key is not set, and validates against it when it is set.test/bin/npx-cli.js: npx does not read a lazily typed definition.Results on Windows 11, Node 26.7.0:
node . run test -w workspaces/config: passes, 100% coverage;node . run lint: clean;node . run test: passes excepttest/bin/windows-shims.js,test/lib/commands/publish.jsand
test/lib/commands/stage/index.js, which fail the same way on unmodifiedlateston thetest machine (a PowerShell profile message, and scripts that call
touch).On Linux, the config workspace passes with 100% coverage.
Composition
PRs fix: refresh npx cache for local bin changes #9767, fix(libnpmexec): honor min-release-age-exclude in npx #9768, fix(libnpmexec): honor min-release-age-exclude when resolving specs #9944, fix(exec): don't inherit global config when installing to the npx cache #10042, fix(libnpmexec): escape inferred executable names for selected shell #10044 and fix: skip disconnected orphans in install script checks #10068.
workspaces/config/lib/index.jsandworkspaces/config/test/index.js;the two merge automatically.