123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- .TH "FOLDERS" "5" "August 2021" "" ""
- .SH "NAME"
- \fBfolders\fR \- Folder Structures Used by npm
- .SS Description
- .P
- npm puts various things on your computer\. That's its job\.
- .P
- This document will tell you what it puts where\.
- .SS tl;dr
- .RS 0
- .IP \(bu 2
- Local install (default): puts stuff in \fB\|\./node_modules\fP of the current
- package root\.
- .IP \(bu 2
- Global install (with \fB\-g\fP): puts stuff in /usr/local or wherever node
- is installed\.
- .IP \(bu 2
- Install it \fBlocally\fR if you're going to \fBrequire()\fP it\.
- .IP \(bu 2
- Install it \fBglobally\fR if you're going to run it on the command line\.
- .IP \(bu 2
- If you need both, then install it in both places, or use \fBnpm link\fP\|\.
- .RE
- .SS prefix Configuration
- .P
- The \fBprefix\fP config defaults to the location where node is installed\.
- On most systems, this is \fB/usr/local\fP\|\. On Windows, it's \fB%AppData%\\npm\fP\|\.
- On Unix systems, it's one level up, since node is typically installed at
- \fB{prefix}/bin/node\fP rather than \fB{prefix}/node\.exe\fP\|\.
- .P
- When the \fBglobal\fP flag is set, npm installs things into this prefix\.
- When it is not set, it uses the root of the current package, or the
- current working directory if not in a package already\.
- .SS Node Modules
- .P
- Packages are dropped into the \fBnode_modules\fP folder under the \fBprefix\fP\|\.
- When installing locally, this means that you can
- \fBrequire("packagename")\fP to load its main module, or
- \fBrequire("packagename/lib/path/to/sub/module")\fP to load other modules\.
- .P
- Global installs on Unix systems go to \fB{prefix}/lib/node_modules\fP\|\.
- Global installs on Windows go to \fB{prefix}/node_modules\fP (that is, no
- \fBlib\fP folder\.)
- .P
- Scoped packages are installed the same way, except they are grouped together
- in a sub\-folder of the relevant \fBnode_modules\fP folder with the name of that
- scope prefix by the @ symbol, e\.g\. \fBnpm install @myorg/package\fP would place
- the package in \fB{prefix}/node_modules/@myorg/package\fP\|\. See npm help \fBscope\fP for more details\.
- .P
- If you wish to \fBrequire()\fP a package, then install it locally\.
- .SS Executables
- .P
- When in global mode, executables are linked into \fB{prefix}/bin\fP on Unix,
- or directly into \fB{prefix}\fP on Windows\.
- .P
- When in local mode, executables are linked into
- \fB\|\./node_modules/\.bin\fP so that they can be made available to scripts run
- through npm\. (For example, so that a test runner will be in the path
- when you run \fBnpm test\fP\|\.)
- .SS Man Pages
- .P
- When in global mode, man pages are linked into \fB{prefix}/share/man\fP\|\.
- .P
- When in local mode, man pages are not installed\.
- .P
- Man pages are not installed on Windows systems\.
- .SS Cache
- .P
- See npm help \fBcache\fP\|\. Cache files are stored in \fB~/\.npm\fP on Posix, or
- \fB%AppData%/npm\-cache\fP on Windows\.
- .P
- This is controlled by the \fBcache\fP configuration param\.
- .SS Temp Files
- .P
- Temporary files are stored by default in the folder specified by the
- \fBtmp\fP config, which defaults to the TMPDIR, TMP, or TEMP environment
- variables, or \fB/tmp\fP on Unix and \fBc:\\windows\\temp\fP on Windows\.
- .P
- Temp files are given a unique folder under this root for each run of the
- program, and are deleted upon successful exit\.
- .SS More Information
- .P
- When installing locally, npm first tries to find an appropriate
- \fBprefix\fP folder\. This is so that \fBnpm install foo@1\.2\.3\fP will install
- to the sensible root of your package, even if you happen to have \fBcd\fPed
- into some other folder\.
- .P
- Starting at the $PWD, npm will walk up the folder tree checking for a
- folder that contains either a \fBpackage\.json\fP file, or a \fBnode_modules\fP
- folder\. If such a thing is found, then that is treated as the effective
- "current directory" for the purpose of running npm commands\. (This
- behavior is inspired by and similar to git's \.git\-folder seeking
- logic when running git commands in a working dir\.)
- .P
- If no package root is found, then the current folder is used\.
- .P
- When you run \fBnpm install foo@1\.2\.3\fP, then the package is loaded into
- the cache, and then unpacked into \fB\|\./node_modules/foo\fP\|\. Then, any of
- foo's dependencies are similarly unpacked into
- \fB\|\./node_modules/foo/node_modules/\.\.\.\fP\|\.
- .P
- Any bin files are symlinked to \fB\|\./node_modules/\.bin/\fP, so that they may
- be found by npm scripts when necessary\.
- .SS Global Installation
- .P
- If the \fBglobal\fP configuration is set to true, then npm will
- install packages "globally"\.
- .P
- For global installation, packages are installed roughly the same way,
- but using the folders described above\.
- .SS Cycles, Conflicts, and Folder Parsimony
- .P
- Cycles are handled using the property of node's module system that it
- walks up the directories looking for \fBnode_modules\fP folders\. So, at every
- stage, if a package is already installed in an ancestor \fBnode_modules\fP
- folder, then it is not installed at the current location\.
- .P
- Consider the case above, where \fBfoo \-> bar \-> baz\fP\|\. Imagine if, in
- addition to that, baz depended on bar, so you'd have:
- \fBfoo \-> bar \-> baz \-> bar \-> baz \.\.\.\fP\|\. However, since the folder
- structure is: \fBfoo/node_modules/bar/node_modules/baz\fP, there's no need to
- put another copy of bar into \fB\|\.\.\./baz/node_modules\fP, since when it calls
- require("bar"), it will get the copy that is installed in
- \fBfoo/node_modules/bar\fP\|\.
- .P
- This shortcut is only used if the exact same
- version would be installed in multiple nested \fBnode_modules\fP folders\. It
- is still possible to have \fBa/node_modules/b/node_modules/a\fP if the two
- "a" packages are different versions\. However, without repeating the
- exact same package multiple times, an infinite regress will always be
- prevented\.
- .P
- Another optimization can be made by installing dependencies at the
- highest level possible, below the localized "target" folder\.
- .SS Example
- .P
- Consider this dependency graph:
- .P
- .RS 2
- .nf
- foo
- +\-\- blerg@1\.2\.5
- +\-\- bar@1\.2\.3
- | +\-\- blerg@1\.x (latest=1\.3\.7)
- | +\-\- baz@2\.x
- | | `\-\- quux@3\.x
- | | `\-\- bar@1\.2\.3 (cycle)
- | `\-\- asdf@*
- `\-\- baz@1\.2\.3
- `\-\- quux@3\.x
- `\-\- bar
- .fi
- .RE
- .P
- In this case, we might expect a folder structure like this:
- .P
- .RS 2
- .nf
- foo
- +\-\- node_modules
- +\-\- blerg (1\.2\.5) <\-\-\-[A]
- +\-\- bar (1\.2\.3) <\-\-\-[B]
- | `\-\- node_modules
- | +\-\- baz (2\.0\.2) <\-\-\-[C]
- | | `\-\- node_modules
- | | `\-\- quux (3\.2\.0)
- | `\-\- asdf (2\.3\.4)
- `\-\- baz (1\.2\.3) <\-\-\-[D]
- `\-\- node_modules
- `\-\- quux (3\.2\.0) <\-\-\-[E]
- .fi
- .RE
- .P
- Since foo depends directly on \fBbar@1\.2\.3\fP and \fBbaz@1\.2\.3\fP, those are
- installed in foo's \fBnode_modules\fP folder\.
- .P
- Even though the latest copy of blerg is 1\.3\.7, foo has a specific
- dependency on version 1\.2\.5\. So, that gets installed at [A]\. Since the
- parent installation of blerg satisfies bar's dependency on \fBblerg@1\.x\fP,
- it does not install another copy under [B]\.
- .P
- Bar [B] also has dependencies on baz and asdf, so those are installed in
- bar's \fBnode_modules\fP folder\. Because it depends on \fBbaz@2\.x\fP, it cannot
- re\-use the \fBbaz@1\.2\.3\fP installed in the parent \fBnode_modules\fP folder [D],
- and must install its own copy [C]\.
- .P
- Underneath bar, the \fBbaz \-> quux \-> bar\fP dependency creates a cycle\.
- However, because bar is already in quux's ancestry [B], it does not
- unpack another copy of bar into that folder\.
- .P
- Underneath \fBfoo \-> baz\fP [D], quux's [E] folder tree is empty, because its
- dependency on bar is satisfied by the parent folder copy installed at [B]\.
- .P
- For a graphical breakdown of what is installed where, use \fBnpm ls\fP\|\.
- .SS Publishing
- .P
- Upon publishing, npm will look in the \fBnode_modules\fP folder\. If any of
- the items there are not in the \fBbundledDependencies\fP array, then they will
- not be included in the package tarball\.
- .P
- This allows a package maintainer to install all of their dependencies
- (and dev dependencies) locally, but only re\-publish those items that
- cannot be found elsewhere\. See npm help \fBpackage\.json\fP for more information\.
- .SS See also
- .RS 0
- .IP \(bu 2
- npm help package\.json
- .IP \(bu 2
- npm help install
- .IP \(bu 2
- npm help pack
- .IP \(bu 2
- npm help cache
- .IP \(bu 2
- npm help config
- .IP \(bu 2
- npm help npmrc
- .IP \(bu 2
- npm help config
- .IP \(bu 2
- npm help publish
- .RE
|