mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
14 KiB
224 lines
14 KiB
<!doctype html>
|
|
<html>
|
|
<title>npm-scripts</title>
|
|
<meta http-equiv="content-type" value="text/html;utf-8">
|
|
<link rel="stylesheet" type="text/css" href="../../static/style.css">
|
|
<link rel="canonical" href="https://www.npmjs.org/doc/misc/npm-scripts.html">
|
|
<script async=true src="../../static/toc.js"></script>
|
|
|
|
<body>
|
|
<div id="wrapper">
|
|
|
|
<h1><a href="../misc/npm-scripts.html">npm-scripts</a></h1> <p>How npm handles the "scripts" field</p>
|
|
<h2 id="description">DESCRIPTION</h2>
|
|
<p>npm supports the "scripts" property of the package.json script, for the
|
|
following scripts:</p>
|
|
<ul>
|
|
<li>prepublish:
|
|
Run BEFORE the package is published. (Also run on local <code>npm
|
|
install</code> without any arguments.)</li>
|
|
<li>publish, postpublish:
|
|
Run AFTER the package is published.</li>
|
|
<li>preinstall:
|
|
Run BEFORE the package is installed</li>
|
|
<li>install, postinstall:
|
|
Run AFTER the package is installed.</li>
|
|
<li>preuninstall, uninstall:
|
|
Run BEFORE the package is uninstalled.</li>
|
|
<li>postuninstall:
|
|
Run AFTER the package is uninstalled.</li>
|
|
<li>preupdate:
|
|
Run BEFORE the package is updated with the update command.</li>
|
|
<li>update, postupdate:
|
|
Run AFTER the package is updated with the update command.</li>
|
|
<li>pretest, test, posttest:
|
|
Run by the <code>npm test</code> command.</li>
|
|
<li>prestop, stop, poststop:
|
|
Run by the <code>npm stop</code> command.</li>
|
|
<li>prestart, start, poststart:
|
|
Run by the <code>npm start</code> command.</li>
|
|
<li>prerestart, restart, postrestart:
|
|
Run by the <code>npm restart</code> command. Note: <code>npm restart</code> will run the
|
|
stop and start scripts if no <code>restart</code> script is provided.</li>
|
|
</ul>
|
|
<p>Additionally, arbitrary scripts can be executed by running <code>npm
|
|
run-script <pkg> <stage></code>. <em>Pre</em> and <em>post</em> commands with matching
|
|
names will be run for those as well (e.g. <code>premyscript</code>, <code>myscript</code>,
|
|
<code>postmyscript</code>).</p>
|
|
<h2 id="note-install-scripts-are-an-antipattern">NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN</h2>
|
|
<p><strong>tl;dr</strong> Don't use <code>install</code>. Use a <code>.gyp</code> file for compilation, and
|
|
<code>prepublish</code> for anything else.</p>
|
|
<p>You should almost never have to explicitly set a <code>preinstall</code> or
|
|
<code>install</code> script. If you are doing this, please consider if there is
|
|
another option.</p>
|
|
<p>The only valid use of <code>install</code> or <code>preinstall</code> scripts is for
|
|
compilation which must be done on the target architecture. In early
|
|
versions of node, this was often done using the <code>node-waf</code> scripts, or
|
|
a standalone <code>Makefile</code>, and early versions of npm required that it be
|
|
explicitly set in package.json. This was not portable, and harder to
|
|
do properly.</p>
|
|
<p>In the current version of node, the standard way to do this is using a
|
|
<code>.gyp</code> file. If you have a file with a <code>.gyp</code> extension in the root
|
|
of your package, then npm will run the appropriate <code>node-gyp</code> commands
|
|
automatically at install time. This is the only officially supported
|
|
method for compiling binary addons, and does not require that you add
|
|
anything to your package.json file.</p>
|
|
<p>If you have to do other things before your package is used, in a way
|
|
that is not dependent on the operating system or architecture of the
|
|
target system, then use a <code>prepublish</code> script instead. This includes
|
|
tasks such as:</p>
|
|
<ul>
|
|
<li>Compile CoffeeScript source code into JavaScript.</li>
|
|
<li>Create minified versions of JavaScript source code.</li>
|
|
<li>Fetching remote resources that your package will use.</li>
|
|
</ul>
|
|
<p>The advantage of doing these things at <code>prepublish</code> time instead of
|
|
<code>preinstall</code> or <code>install</code> time is that they can be done once, in a
|
|
single place, and thus greatly reduce complexity and variability.
|
|
Additionally, this means that:</p>
|
|
<ul>
|
|
<li>You can depend on <code>coffee-script</code> as a <code>devDependency</code>, and thus
|
|
your users don't need to have it installed.</li>
|
|
<li>You don't need to include the minifiers in your package, reducing
|
|
the size for your users.</li>
|
|
<li>You don't need to rely on your users having <code>curl</code> or <code>wget</code> or
|
|
other system tools on the target machines.</li>
|
|
</ul>
|
|
<h2 id="default-values">DEFAULT VALUES</h2>
|
|
<p>npm will default some script values based on package contents.</p>
|
|
<ul>
|
|
<li><p><code>"start": "node server.js"</code>:</p>
|
|
<p>If there is a <code>server.js</code> file in the root of your package, then npm
|
|
will default the <code>start</code> command to <code>node server.js</code>.</p>
|
|
</li>
|
|
<li><p><code>"preinstall": "node-waf clean || true; node-waf configure build"</code>:</p>
|
|
<p>If there is a <code>wscript</code> file in the root of your package, npm will
|
|
default the <code>preinstall</code> command to compile using node-waf.</p>
|
|
</li>
|
|
</ul>
|
|
<h2 id="user">USER</h2>
|
|
<p>If npm was invoked with root privileges, then it will change the uid
|
|
to the user account or uid specified by the <code>user</code> config, which
|
|
defaults to <code>nobody</code>. Set the <code>unsafe-perm</code> flag to run scripts with
|
|
root privileges.</p>
|
|
<h2 id="environment">ENVIRONMENT</h2>
|
|
<p>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.</p>
|
|
<h3 id="path">path</h3>
|
|
<p>If you depend on modules that define executable scripts, like test
|
|
suites, then those executables will be added to the <code>PATH</code> for
|
|
executing the scripts. So, if your package.json has this:</p>
|
|
<pre><code>{ "name" : "foo"
|
|
, "dependencies" : { "bar" : "0.1.x" }
|
|
, "scripts": { "start" : "bar ./test" } }
|
|
</code></pre><p>then you could run <code>npm start</code> to execute the <code>bar</code> script, which is
|
|
exported into the <code>node_modules/.bin</code> directory on <code>npm install</code>.</p>
|
|
<h3 id="package-json-vars">package.json vars</h3>
|
|
<p>The package.json fields are tacked onto the <code>npm_package_</code> prefix. So,
|
|
for instance, if you had <code>{"name":"foo", "version":"1.2.5"}</code> in your
|
|
package.json file, then your package scripts would have the
|
|
<code>npm_package_name</code> environment variable set to "foo", and the
|
|
<code>npm_package_version</code> set to "1.2.5"</p>
|
|
<h3 id="configuration">configuration</h3>
|
|
<p>Configuration parameters are put in the environment with the
|
|
<code>npm_config_</code> prefix. For instance, you can view the effective <code>root</code>
|
|
config by checking the <code>npm_config_root</code> environment variable.</p>
|
|
<h3 id="special-package-json-config-object">Special: package.json "config" object</h3>
|
|
<p>The package.json "config" keys are overwritten in the environment if
|
|
there is a config param of <code><name>[@<version>]:<key></code>. For example,
|
|
if the package.json has this:</p>
|
|
<pre><code>{ "name" : "foo"
|
|
, "config" : { "port" : "8080" }
|
|
, "scripts" : { "start" : "node server.js" } }
|
|
</code></pre><p>and the server.js is this:</p>
|
|
<pre><code>http.createServer(...).listen(process.env.npm_package_config_port)
|
|
</code></pre><p>then the user could change the behavior by doing:</p>
|
|
<pre><code>npm config set foo:port 80
|
|
</code></pre><h3 id="current-lifecycle-event">current lifecycle event</h3>
|
|
<p>Lastly, the <code>npm_lifecycle_event</code> 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>
|
|
<p>Objects are flattened following this format, so if you had
|
|
<code>{"scripts":{"install":"foo.js"}}</code> in your package.json, then you'd
|
|
see this in the script:</p>
|
|
<pre><code>process.env.npm_package_scripts_install === "foo.js"
|
|
</code></pre><h2 id="examples">EXAMPLES</h2>
|
|
<p>For example, if your package.json contains this:</p>
|
|
<pre><code>{ "scripts" :
|
|
{ "install" : "scripts/install.js"
|
|
, "postinstall" : "scripts/install.js"
|
|
, "uninstall" : "scripts/uninstall.js"
|
|
}
|
|
}
|
|
</code></pre><p>then the <code>scripts/install.js</code> will be called for the install,
|
|
post-install, stages of the lifecycle, and the <code>scripts/uninstall.js</code>
|
|
would be called when the package is uninstalled. Since
|
|
<code>scripts/install.js</code> is running for three different phases, it would
|
|
be wise in this case to look at the <code>npm_lifecycle_event</code> environment
|
|
variable.</p>
|
|
<p>If you want to run a make command, you can do so. This works just
|
|
fine:</p>
|
|
<pre><code>{ "scripts" :
|
|
{ "preinstall" : "./configure"
|
|
, "install" : "make && make install"
|
|
, "test" : "make test"
|
|
}
|
|
}
|
|
</code></pre><h2 id="exiting">EXITING</h2>
|
|
<p>Scripts are run by passing the line as a script argument to <code>sh</code>.</p>
|
|
<p>If the script exits with a code other than 0, then this will abort the
|
|
process.</p>
|
|
<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.</p>
|
|
<h2 id="hook-scripts">HOOK SCRIPTS</h2>
|
|
<p>If you want to run a specific script at a specific lifecycle event for
|
|
ALL packages, then you can use a hook script.</p>
|
|
<p>Place an executable file at <code>node_modules/.hooks/{eventname}</code>, 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>
|
|
<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.</p>
|
|
<h2 id="best-practices">BEST PRACTICES</h2>
|
|
<ul>
|
|
<li>Don't exit with a non-zero error code unless you <em>really</em> 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.</li>
|
|
<li>Try not to use scripts to do what npm can do for you. Read through
|
|
<code><a href="../files/package.json.html"><a href="../files/package.json.html">package.json(5)</a></a></code> 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.</li>
|
|
<li>Inspect the env to determine where to put things. For instance, if
|
|
the <code>npm_config_binroot</code> environ is set to <code>/home/user/bin</code>, then
|
|
don't try to install executables into <code>/usr/local/bin</code>. The user
|
|
probably set it up that way for a reason.</li>
|
|
<li>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.</li>
|
|
</ul>
|
|
<h2 id="see-also">SEE ALSO</h2>
|
|
<ul>
|
|
<li><a href="../cli/npm-run-script.html"><a href="../cli/npm-run-script.html">npm-run-script(1)</a></a></li>
|
|
<li><a href="../files/package.json.html"><a href="../files/package.json.html">package.json(5)</a></a></li>
|
|
<li><a href="../misc/npm-developers.html"><a href="../misc/npm-developers.html">npm-developers(7)</a></a></li>
|
|
<li><a href="../cli/npm-install.html"><a href="../cli/npm-install.html">npm-install(1)</a></a></li>
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
<table border=0 cellspacing=0 cellpadding=0 id=npmlogo>
|
|
<tr><td style="width:180px;height:10px;background:rgb(237,127,127)" colspan=18> </td></tr>
|
|
<tr><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)"> </td><td style="width:40px;height:10px;background:#fff" colspan=4> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4> </td><td style="width:40px;height:10px;background:#fff" colspan=4> </td><td rowspan=4 style="width:10px;height:10px;background:rgb(237,127,127)"> </td><td colspan=6 style="width:60px;height:10px;background:#fff"> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=4> </td></tr>
|
|
<tr><td colspan=2 style="width:20px;height:30px;background:#fff" rowspan=3> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3> </td><td style="width:10px;height:10px;background:#fff" rowspan=3> </td><td style="width:20px;height:10px;background:#fff" rowspan=4 colspan=2> </td><td style="width:10px;height:20px;background:rgb(237,127,127)" rowspan=2> </td><td style="width:10px;height:10px;background:#fff" rowspan=3> </td><td style="width:20px;height:10px;background:#fff" rowspan=3 colspan=2> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3> </td><td style="width:10px;height:10px;background:#fff" rowspan=3> </td><td style="width:10px;height:10px;background:rgb(237,127,127)" rowspan=3> </td></tr>
|
|
<tr><td style="width:10px;height:10px;background:#fff" rowspan=2> </td></tr>
|
|
<tr><td style="width:10px;height:10px;background:#fff"> </td></tr>
|
|
<tr><td style="width:60px;height:10px;background:rgb(237,127,127)" colspan=6> </td><td colspan=10 style="width:10px;height:10px;background:rgb(237,127,127)"> </td></tr>
|
|
<tr><td colspan=5 style="width:50px;height:10px;background:#fff"> </td><td style="width:40px;height:10px;background:rgb(237,127,127)" colspan=4> </td><td style="width:90px;height:10px;background:#fff" colspan=9> </td></tr>
|
|
</table>
|
|
<p id="footer">npm-scripts — npm@2.1.6</p>
|
|
|
|
|