291 lines
8.4 KiB
Groff
291 lines
8.4 KiB
Groff
|
.TH "DEVELOPERS" "7" "February 2022" "" ""
|
||
|
.SH "NAME"
|
||
|
\fBdevelopers\fR \- Developer Guide
|
||
|
.SS Description
|
||
|
.P
|
||
|
So, you've decided to use npm to develop (and maybe publish/deploy)
|
||
|
your project\.
|
||
|
.P
|
||
|
Fantastic!
|
||
|
.P
|
||
|
There are a few things that you need to do above the simple steps
|
||
|
that your users will do to install your program\.
|
||
|
.SS About These Documents
|
||
|
.P
|
||
|
These are man pages\. If you install npm, you should be able to
|
||
|
then do \fBman npm\-thing\fP to get the documentation on a particular
|
||
|
topic, or \fBnpm help thing\fP to see the same information\.
|
||
|
.SS What is a Package
|
||
|
.P
|
||
|
A package is:
|
||
|
.RS 0
|
||
|
.IP \(bu 2
|
||
|
a) a folder containing a program described by a package\.json file
|
||
|
.IP \(bu 2
|
||
|
b) a gzipped tarball containing (a)
|
||
|
.IP \(bu 2
|
||
|
c) a url that resolves to (b)
|
||
|
.IP \(bu 2
|
||
|
d) a \fB<name>@<version>\fP that is published on the registry with (c)
|
||
|
.IP \(bu 2
|
||
|
e) a \fB<name>@<tag>\fP that points to (d)
|
||
|
.IP \(bu 2
|
||
|
f) a \fB<name>\fP that has a "latest" tag satisfying (e)
|
||
|
.IP \(bu 2
|
||
|
g) a \fBgit\fP url that, when cloned, results in (a)\.
|
||
|
|
||
|
.RE
|
||
|
.P
|
||
|
Even if you never publish your package, you can still get a lot of
|
||
|
benefits of using npm if you just want to write a node program (a), and
|
||
|
perhaps if you also want to be able to easily install it elsewhere
|
||
|
after packing it up into a tarball (b)\.
|
||
|
.P
|
||
|
Git urls can be of the form:
|
||
|
.P
|
||
|
.RS 2
|
||
|
.nf
|
||
|
git://github\.com/user/project\.git#commit\-ish
|
||
|
git+ssh://user@hostname:project\.git#commit\-ish
|
||
|
git+http://user@hostname/project/blah\.git#commit\-ish
|
||
|
git+https://user@hostname/project/blah\.git#commit\-ish
|
||
|
.fi
|
||
|
.RE
|
||
|
.P
|
||
|
The \fBcommit\-ish\fP can be any tag, sha, or branch which can be supplied as
|
||
|
an argument to \fBgit checkout\fP\|\. The default is whatever the repository uses
|
||
|
as its default branch\.
|
||
|
.SS The package\.json File
|
||
|
.P
|
||
|
You need to have a \fBpackage\.json\fP file in the root of your project to do
|
||
|
much of anything with npm\. That is basically the whole interface\.
|
||
|
.P
|
||
|
See npm help \fBpackage\.json\fP for details about what
|
||
|
goes in that file\. At the very least, you need:
|
||
|
.RS 0
|
||
|
.IP \(bu 2
|
||
|
name: This should be a string that identifies your project\. Please do
|
||
|
not use the name to specify that it runs on node, or is in JavaScript\.
|
||
|
You can use the "engines" field to explicitly state the versions of node
|
||
|
(or whatever else) that your program requires, and it's pretty well
|
||
|
assumed that it's JavaScript\.
|
||
|
It does not necessarily need to match your github repository name\.
|
||
|
So, \fBnode\-foo\fP and \fBbar\-js\fP are bad names\. \fBfoo\fP or \fBbar\fP are better\.
|
||
|
.IP \(bu 2
|
||
|
version: A semver\-compatible version\.
|
||
|
.IP \(bu 2
|
||
|
engines: Specify the versions of node (or whatever else) that your
|
||
|
program runs on\. The node API changes a lot, and there may be bugs or
|
||
|
new functionality that you depend on\. Be explicit\.
|
||
|
.IP \(bu 2
|
||
|
author: Take some credit\.
|
||
|
.IP \(bu 2
|
||
|
scripts: If you have a special compilation or installation script, then
|
||
|
you should put it in the \fBscripts\fP object\. You should definitely have at
|
||
|
least a basic smoke\-test command as the "scripts\.test" field\. See
|
||
|
npm help scripts\.
|
||
|
.IP \(bu 2
|
||
|
main: If you have a single module that serves as the entry point to your
|
||
|
program (like what the "foo" package gives you at require("foo")), then
|
||
|
you need to specify that in the "main" field\.
|
||
|
.IP \(bu 2
|
||
|
directories: This is an object mapping names to folders\. The best ones
|
||
|
to include are "lib" and "doc", but if you use "man" to specify a folder
|
||
|
full of man pages, they'll get installed just like these ones\.
|
||
|
|
||
|
.RE
|
||
|
.P
|
||
|
You can use \fBnpm init\fP in the root of your package in order to get you
|
||
|
started with a pretty basic package\.json file\. See npm help \fBnpm
|
||
|
init\fP for more info\.
|
||
|
.SS Keeping files \fIout\fR of your Package
|
||
|
.P
|
||
|
Use a \fB\|\.npmignore\fP file to keep stuff out of your package\. If there's no
|
||
|
\fB\|\.npmignore\fP file, but there \fIis\fR a \fB\|\.gitignore\fP file, then npm will ignore
|
||
|
the stuff matched by the \fB\|\.gitignore\fP file\. If you \fIwant\fR to include
|
||
|
something that is excluded by your \fB\|\.gitignore\fP file, you can create an
|
||
|
empty \fB\|\.npmignore\fP file to override it\. Like \fBgit\fP, \fBnpm\fP looks for
|
||
|
\fB\|\.npmignore\fP and \fB\|\.gitignore\fP files in all subdirectories of your package,
|
||
|
not only the root directory\.
|
||
|
.P
|
||
|
\fB\|\.npmignore\fP files follow the same pattern
|
||
|
rules \fIhttps://git\-scm\.com/book/en/v2/Git\-Basics\-Recording\-Changes\-to\-the\-Repository#_ignoring\fR
|
||
|
as \fB\|\.gitignore\fP files:
|
||
|
.RS 0
|
||
|
.IP \(bu 2
|
||
|
Blank lines or lines starting with \fB#\fP are ignored\.
|
||
|
.IP \(bu 2
|
||
|
Standard glob patterns work\.
|
||
|
.IP \(bu 2
|
||
|
You can end patterns with a forward slash \fB/\fP to specify a directory\.
|
||
|
.IP \(bu 2
|
||
|
You can negate a pattern by starting it with an exclamation point \fB!\fP\|\.
|
||
|
|
||
|
.RE
|
||
|
.P
|
||
|
By default, the following paths and files are ignored, so there's no
|
||
|
need to add them to \fB\|\.npmignore\fP explicitly:
|
||
|
.RS 0
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.*\.swp\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\._*\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.DS_Store\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.git\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.gitignore\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.hg\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.npmignore\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.npmrc\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.lock\-wscript\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.svn\fP
|
||
|
.IP \(bu 2
|
||
|
\fB\|\.wafpickle\-*\fP
|
||
|
.IP \(bu 2
|
||
|
\fBconfig\.gypi\fP
|
||
|
.IP \(bu 2
|
||
|
\fBCVS\fP
|
||
|
.IP \(bu 2
|
||
|
\fBnpm\-debug\.log\fP
|
||
|
|
||
|
.RE
|
||
|
.P
|
||
|
Additionally, everything in \fBnode_modules\fP is ignored, except for
|
||
|
bundled dependencies\. npm automatically handles this for you, so don't
|
||
|
bother adding \fBnode_modules\fP to \fB\|\.npmignore\fP\|\.
|
||
|
.P
|
||
|
The following paths and files are never ignored, so adding them to
|
||
|
\fB\|\.npmignore\fP is pointless:
|
||
|
.RS 0
|
||
|
.IP \(bu 2
|
||
|
\fBpackage\.json\fP
|
||
|
.IP \(bu 2
|
||
|
\fBREADME\fP (and its variants)
|
||
|
.IP \(bu 2
|
||
|
\fBCHANGELOG\fP (and its variants)
|
||
|
.IP \(bu 2
|
||
|
\fBLICENSE\fP / \fBLICENCE\fP
|
||
|
|
||
|
.RE
|
||
|
.P
|
||
|
If, given the structure of your project, you find \fB\|\.npmignore\fP to be a
|
||
|
maintenance headache, you might instead try populating the \fBfiles\fP
|
||
|
property of \fBpackage\.json\fP, which is an array of file or directory names
|
||
|
that should be included in your package\. Sometimes manually picking
|
||
|
which items to allow is easier to manage than building a block list\.
|
||
|
.SS Testing whether your \fB\|\.npmignore\fP or \fBfiles\fP config works
|
||
|
.P
|
||
|
If you want to double check that your package will include only the files
|
||
|
you intend it to when published, you can run the \fBnpm pack\fP command locally
|
||
|
which will generate a tarball in the working directory, the same way it
|
||
|
does for publishing\.
|
||
|
.SS Link Packages
|
||
|
.P
|
||
|
\fBnpm link\fP is designed to install a development package and see the
|
||
|
changes in real time without having to keep re\-installing it\. (You do
|
||
|
need to either re\-link or \fBnpm rebuild \-g\fP to update compiled packages,
|
||
|
of course\.)
|
||
|
.P
|
||
|
More info at npm help \fBlink\fP\|\.
|
||
|
.SS Before Publishing: Make Sure Your Package Installs and Works
|
||
|
.P
|
||
|
\fBThis is important\.\fR
|
||
|
.P
|
||
|
If you can not install it locally, you'll have
|
||
|
problems trying to publish it\. Or, worse yet, you'll be able to
|
||
|
publish it, but you'll be publishing a broken or pointless package\.
|
||
|
So don't do that\.
|
||
|
.P
|
||
|
In the root of your package, do this:
|
||
|
.P
|
||
|
.RS 2
|
||
|
.nf
|
||
|
npm install \. \-g
|
||
|
.fi
|
||
|
.RE
|
||
|
.P
|
||
|
That'll show you that it's working\. If you'd rather just create a symlink
|
||
|
package that points to your working directory, then do this:
|
||
|
.P
|
||
|
.RS 2
|
||
|
.nf
|
||
|
npm link
|
||
|
.fi
|
||
|
.RE
|
||
|
.P
|
||
|
Use \fBnpm ls \-g\fP to see if it's there\.
|
||
|
.P
|
||
|
To test a local install, go into some other folder, and then do:
|
||
|
.P
|
||
|
.RS 2
|
||
|
.nf
|
||
|
cd \.\./some\-other\-folder
|
||
|
npm install \.\./my\-package
|
||
|
.fi
|
||
|
.RE
|
||
|
.P
|
||
|
to install it locally into the node_modules folder in that other place\.
|
||
|
.P
|
||
|
Then go into the node\-repl, and try using require("my\-thing") to
|
||
|
bring in your module's main module\.
|
||
|
.SS Create a User Account
|
||
|
.P
|
||
|
Create a user with the adduser command\. It works like this:
|
||
|
.P
|
||
|
.RS 2
|
||
|
.nf
|
||
|
npm adduser
|
||
|
.fi
|
||
|
.RE
|
||
|
.P
|
||
|
and then follow the prompts\.
|
||
|
.P
|
||
|
This is documented better in npm help adduser\.
|
||
|
.SS Publish your Package
|
||
|
.P
|
||
|
This part's easy\. In the root of your folder, do this:
|
||
|
.P
|
||
|
.RS 2
|
||
|
.nf
|
||
|
npm publish
|
||
|
.fi
|
||
|
.RE
|
||
|
.P
|
||
|
You can give publish a url to a tarball, or a filename of a tarball,
|
||
|
or a path to a folder\.
|
||
|
.P
|
||
|
Note that pretty much \fBeverything in that folder will be exposed\fR
|
||
|
by default\. So, if you have secret stuff in there, use a
|
||
|
\fB\|\.npmignore\fP file to list out the globs to ignore, or publish
|
||
|
from a fresh checkout\.
|
||
|
.SS Brag about it
|
||
|
.P
|
||
|
Send emails, write blogs, blab in IRC\.
|
||
|
.P
|
||
|
Tell the world how easy it is to install your program!
|
||
|
.SS See also
|
||
|
.RS 0
|
||
|
.IP \(bu 2
|
||
|
npm help npm
|
||
|
.IP \(bu 2
|
||
|
npm help init
|
||
|
.IP \(bu 2
|
||
|
npm help package\.json
|
||
|
.IP \(bu 2
|
||
|
npm help scripts
|
||
|
.IP \(bu 2
|
||
|
npm help publish
|
||
|
.IP \(bu 2
|
||
|
npm help adduser
|
||
|
.IP \(bu 2
|
||
|
npm help registry
|
||
|
|
||
|
.RE
|