|
|
|
.\" Generated with Ronnjs/v0.1
|
|
|
|
.\" http://github.com/kapouer/ronnjs/
|
|
|
|
.
|
|
|
|
.TH "NPM\-SCRIPTS" "1" "June 2012" "" ""
|
|
|
|
.
|
|
|
|
.SH "NAME"
|
|
|
|
\fBnpm-scripts\fR \-\- How npm handles the "scripts" field
|
|
|
|
.
|
|
|
|
.SH "DESCRIPTION"
|
|
|
|
npm supports the "scripts" member of the package\.json script, for the
|
|
|
|
following scripts:
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
preinstall:
|
|
|
|
Run BEFORE the package is installed
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
install, postinstall:
|
|
|
|
Run AFTER the package is installed\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
preuninstall, uninstall:
|
|
|
|
Run BEFORE the package is uninstalled\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
postuninstall:
|
|
|
|
Run AFTER the package is uninstalled\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
preupdate:
|
|
|
|
Run BEFORE the package is updated with the update command\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
update, postupdate:
|
|
|
|
Run AFTER the package is updated with the update command\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
prepublish:
|
|
|
|
Run BEFORE the package is published\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
publish, postpublish:
|
|
|
|
Run AFTER the package is published\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
pretest, test, posttest:
|
|
|
|
Run by the \fBnpm test\fR command\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
prestop, stop, poststop:
|
|
|
|
Run by the \fBnpm stop\fR command\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
prestart, start, poststart:
|
|
|
|
Run by the \fBnpm start\fR command\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
prerestart, restart, postrestart:
|
|
|
|
Run by the \fBnpm restart\fR command\. Note: \fBnpm restart\fR will run the
|
|
|
|
stop and start scripts if no \fBrestart\fR script is provided\.
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
Additionally, arbitrary scrips can be run by doing \fBnpm run\-script <stage> <pkg>\fR\|\.
|
|
|
|
.
|
|
|
|
.SH "DEFAULT VALUES"
|
|
|
|
npm will default some script values based on package contents\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
\fB"start": "node server\.js"\fR:
|
|
|
|
.
|
|
|
|
.IP
|
|
|
|
If there is a \fBserver\.js\fR file in the root of your package, then npm
|
|
|
|
will default the \fBstart\fR command to \fBnode server\.js\fR\|\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
\fB"preinstall": "node\-waf clean || true; node\-waf configure build"\fR:
|
|
|
|
.
|
|
|
|
.IP
|
|
|
|
If there is a \fBwscript\fR file in the root of your package, npm will
|
|
|
|
default the \fBpreinstall\fR command to compile using node\-waf\.
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.SH "USER"
|
|
|
|
If npm was invoked with root privileges, then it will change the uid to
|
|
|
|
the user account or uid specified by the \fBuser\fR config, which defaults
|
|
|
|
to \fBnobody\fR\|\. Set the \fBunsafe\-perm\fR flag to run scripts with root
|
|
|
|
privileges\.
|
|
|
|
.
|
|
|
|
.SH "ENVIRONMENT"
|
|
|
|
Package scripts run in an environment where many pieces of information are
|
|
|
|
made available regarding the setup of npm and the current state of the
|
|
|
|
process\.
|
|
|
|
.
|
|
|
|
.SS "path"
|
|
|
|
If you depend on modules that define executable scripts, like test suites,
|
|
|
|
then those executables will be added to the \fBPATH\fR for executing the scripts\.
|
|
|
|
So, if your package\.json has this:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
{ "name" : "foo"
|
|
|
|
, "dependencies" : { "bar" : "0\.1\.x" }
|
|
|
|
, "scripts": { "start" : "bar \./test" } }
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
then you could run \fBnpm start\fR to execute the \fBbar\fR script, which is exported
|
|
|
|
into the \fBnode_modules/\.bin\fR directory on \fBnpm install\fR\|\.
|
|
|
|
.
|
|
|
|
.SS "package\.json vars"
|
|
|
|
The package\.json fields are tacked onto the \fBnpm_package_\fR prefix\. So, for
|
|
|
|
instance, if you had \fB{"name":"foo", "version":"1\.2\.5"}\fR in your package\.json
|
|
|
|
file, then your package scripts would have the \fBnpm_package_name\fR environment
|
|
|
|
variable set to "foo", and the \fBnpm_package_version\fR set to "1\.2\.5"
|
|
|
|
.
|
|
|
|
.SS "configuration"
|
|
|
|
Configuration parameters are put in the environment with the \fBnpm_config_\fR
|
|
|
|
prefix\. For instance, you can view the effective \fBroot\fR config by checking the \fBnpm_config_root\fR environment variable\.
|
|
|
|
.
|
|
|
|
.SS "Special: package\.json "config" hash"
|
|
|
|
The package\.json "config" keys are overwritten in the environment if
|
|
|
|
there is a config param of \fB<name>[@<version>]:<key>\fR\|\. For example, if
|
|
|
|
the package\.json has this:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
{ "name" : "foo"
|
|
|
|
, "config" : { "port" : "8080" }
|
|
|
|
, "scripts" : { "start" : "node server\.js" } }
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
and the server\.js is this:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
http\.createServer(\.\.\.)\.listen(process\.env\.npm_package_config_port)
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
then the user could change the behavior by doing:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
npm config set foo:port 80
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.SS "current lifecycle event"
|
|
|
|
Lastly, the \fBnpm_lifecycle_event\fR environment variable is set to whichever
|
|
|
|
stage of the cycle is being executed\. So, you could have a single script used
|
|
|
|
for different parts of the process which switches based on what\'s currently
|
|
|
|
happening\.
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
Objects are flattened following this format, so if you had \fB{"scripts":{"install":"foo\.js"}}\fR in your package\.json, then you\'d see this
|
|
|
|
in the script:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
process\.env\.npm_package_scripts_install === "foo\.js"
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.SH "EXAMPLES"
|
|
|
|
For example, if your package\.json contains this:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
{ "scripts" :
|
|
|
|
{ "install" : "scripts/install\.js"
|
|
|
|
, "postinstall" : "scripts/install\.js"
|
|
|
|
, "uninstall" : "scripts/uninstall\.js"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
then the \fBscripts/install\.js\fR will be called for the install, post\-install,
|
|
|
|
stages of the lifecycle, and the \fBscripts/uninstall\.js\fR would be
|
|
|
|
called when the package is uninstalled\. Since \fBscripts/install\.js\fR is running
|
|
|
|
for three different phases, it would be wise in this case to look at the \fBnpm_lifecycle_event\fR environment variable\.
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
If you want to run a make command, you can do so\. This works just fine:
|
|
|
|
.
|
|
|
|
.IP "" 4
|
|
|
|
.
|
|
|
|
.nf
|
|
|
|
{ "scripts" :
|
|
|
|
{ "preinstall" : "\./configure"
|
|
|
|
, "install" : "make && make install"
|
|
|
|
, "test" : "make test"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.
|
|
|
|
.fi
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.SH "EXITING"
|
|
|
|
Scripts are run by passing the line as a script argument to \fBsh\fR\|\.
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
If the script exits with a code other than 0, then this will abort the
|
|
|
|
process\.
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
Note that these script files don\'t have to be nodejs or even javascript
|
|
|
|
programs\. They just have to be some kind of executable file\.
|
|
|
|
.
|
|
|
|
.SH "HOOK SCRIPTS"
|
|
|
|
If you want to run a specific script at a specific lifecycle event for ALL
|
|
|
|
packages, then you can use a hook script\.
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
Place an executable file at \fBnode_modules/\.hooks/{eventname}\fR, and it\'ll get
|
|
|
|
run for all packages when they are going through that point in the package
|
|
|
|
lifecycle for any packages installed in that root\.
|
|
|
|
.
|
|
|
|
.P
|
|
|
|
Hook scripts are run exactly the same way as package\.json scripts\. That is,
|
|
|
|
they are in a separate child process, with the env described above\.
|
|
|
|
.
|
|
|
|
.SH "BEST PRACTICES"
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
Don\'t exit with a non\-zero error code unless you \fIreally\fR mean it\.
|
|
|
|
Except for uninstall scripts, this will cause the npm action
|
|
|
|
to fail, and potentially be rolled back\. If the failure is minor or
|
|
|
|
only will prevent some optional features, then it\'s better to just
|
|
|
|
print a warning and exit successfully\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
Try not to use scripts to do what npm can do for you\. Read through \fBnpm help json\fR to see all the things that you can specify and enable
|
|
|
|
by simply describing your package appropriately\. In general, this will
|
|
|
|
lead to a more robust and consistent state\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
Inspect the env to determine where to put things\. For instance, if
|
|
|
|
the \fBnpm_config_binroot\fR environ is set to \fB/home/user/bin\fR, then don\'t
|
|
|
|
try to install executables into \fB/usr/local/bin\fR\|\. The user probably
|
|
|
|
set it up that way for a reason\.
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
Don\'t prefix your script commands with "sudo"\. If root permissions are
|
|
|
|
required for some reason, then it\'ll fail with that error, and the user
|
|
|
|
will sudo the npm command in question\.
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
.
|
|
|
|
.SH "SEE ALSO"
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
npm help run\-script
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
npm help json
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
npm help developers
|
|
|
|
.
|
|
|
|
.IP "\(bu" 4
|
|
|
|
npm help install
|
|
|
|
.
|
|
|
|
.IP "" 0
|
|
|
|
|