mirror of
https://github.com/titanscouting/tra-analysis.git
synced 2024-11-14 15:16:18 +00:00
227 lines
8.2 KiB
Groff
227 lines
8.2 KiB
Groff
.TH "NPM\-FOLDERS" "5" "December 2018" "" ""
|
|
.SH "NAME"
|
|
\fBnpm-folders\fR \- Folder Structures Used by npm
|
|
.SH 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 7 \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 \fBnpm\-cache\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\.
|
|
.SH 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 \fBand\fP\fB, those are
|
|
installed in foo's\fPnode_modules` 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 `,
|
|
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 \fB, it cannot
|
|
re\-use the\fP\fBinstalled in the parent\fPnode_modules` 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 5 \fBpackage\.json\fP for more information\.
|
|
.SH SEE ALSO
|
|
.RS 0
|
|
.IP \(bu 2
|
|
npm help 5 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 5 npmrc
|
|
.IP \(bu 2
|
|
npm help 7 config
|
|
.IP \(bu 2
|
|
npm help publish
|
|
|
|
.RE
|
|
|