123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- .TH "DEVELOPERS" "7" "August 2021" "" ""
- .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 \fBmaster\fP\|\.
- .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 \fBinit\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\-Files\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\|\.hg\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 a whitelist is easier
- to manage than a blacklist\.
- .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
|