1ffcf8e6fc1f23a276aa4c01aeb036da1944c0e7
[platform/upstream/nodejs.git] / deps / npm / html / doc / misc / npm-scripts.html
1 <!doctype html>
2 <html>
3   <title>npm-scripts</title>
4   <meta http-equiv="content-type" value="text/html;utf-8">
5   <link rel="stylesheet" type="text/css" href="../../static/style.css">
6
7   <body>
8     <div id="wrapper">
9 <h1><a href="../misc/npm-scripts.html">npm-scripts</a></h1> <p>How npm handles the &quot;scripts&quot; field</p>
10
11 <h2 id="DESCRIPTION">DESCRIPTION</h2>
12
13 <p>npm supports the &quot;scripts&quot; member of the package.json script, for the
14 following scripts:</p>
15
16 <ul><li>prepublish:
17 Run BEFORE the package is published.  (Also run on local <code>npm
18 install</code> without any arguments.)</li><li>publish, postpublish:
19 Run AFTER the package is published.</li><li>preinstall:
20 Run BEFORE the package is installed</li><li>install, postinstall:
21 Run AFTER the package is installed.</li><li>preuninstall, uninstall:
22 Run BEFORE the package is uninstalled.</li><li>postuninstall:
23 Run AFTER the package is uninstalled.</li><li>preupdate:
24 Run BEFORE the package is updated with the update command.</li><li>update, postupdate:
25 Run AFTER the package is updated with the update command.</li><li>pretest, test, posttest:
26 Run by the <code>npm test</code> command.</li><li>prestop, stop, poststop:
27 Run by the <code>npm stop</code> command.</li><li>prestart, start, poststart:
28 Run by the <code>npm start</code> command.</li><li>prerestart, restart, postrestart:
29 Run by the <code>npm restart</code> command. Note: <code>npm restart</code> will run the
30 stop and start scripts if no <code>restart</code> script is provided.</li></ul>
31
32 <p>Additionally, arbitrary scripts can be run by doing
33 <code>npm run-script &lt;stage&gt; &lt;pkg&gt;</code>.</p>
34
35 <h2 id="NOTE-INSTALL-SCRIPTS-ARE-AN-ANTIPATTERN">NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN</h2>
36
37 <p><strong>tl;dr</strong> Don&#39;t use <code>install</code>.  Use a <code>.gyp</code> file for compilation, and
38 <code>prepublish</code> for anything else.</p>
39
40 <p>You should almost never have to explicitly set a <code>preinstall</code> or
41 <code>install</code> script.  If you are doing this, please consider if there is
42 another option.</p>
43
44 <p>The only valid use of <code>install</code> or <code>preinstall</code> scripts is for
45 compilation which must be done on the target architecture.  In early
46 versions of node, this was often done using the <code>node-waf</code> scripts, or
47 a standalone <code>Makefile</code>, and early versions of npm required that it be
48 explicitly set in package.json.  This was not portable, and harder to
49 do properly.</p>
50
51 <p>In the current version of node, the standard way to do this is using a
52 <code>.gyp</code> file.  If you have a file with a <code>.gyp</code> extension in the root
53 of your package, then npm will run the appropriate <code>node-gyp</code> commands
54 automatically at install time.  This is the only officially supported
55 method for compiling binary addons, and does not require that you add
56 anything to your package.json file.</p>
57
58 <p>If you have to do other things before your package is used, in a way
59 that is not dependent on the operating system or architecture of the
60 target system, then use a <code>prepublish</code> script instead.  This includes
61 tasks such as:</p>
62
63 <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>
64
65 <p>The advantage of doing these things at <code>prepublish</code> time instead of
66 <code>preinstall</code> or <code>install</code> time is that they can be done once, in a
67 single place, and thus greatly reduce complexity and variability.
68 Additionally, this means that:</p>
69
70 <ul><li>You can depend on <code>coffee-script</code> as a <code>devDependency</code>, and thus
71 your users don&#39;t need to have it installed.</li><li>You don&#39;t need to include the minifiers in your package, reducing
72 the size for your users.</li><li>You don&#39;t need to rely on your users having <code>curl</code> or <code>wget</code> or
73 other system tools on the target machines.</li></ul>
74
75 <h2 id="DEFAULT-VALUES">DEFAULT VALUES</h2>
76
77 <p>npm will default some script values based on package contents.</p>
78
79 <ul><li><p><code>&quot;start&quot;: &quot;node server.js&quot;</code>:</p><p>If there is a <code>server.js</code> file in the root of your package, then npm
80 will default the <code>start</code> command to <code>node server.js</code>.</p></li><li><p><code>&quot;preinstall&quot;: &quot;node-waf clean || true; node-waf configure build&quot;</code>:</p><p>If there is a <code>wscript</code> file in the root of your package, npm will
81 default the <code>preinstall</code> command to compile using node-waf.</p></li></ul>
82
83 <h2 id="USER">USER</h2>
84
85 <p>If npm was invoked with root privileges, then it will change the uid
86 to the user account or uid specified by the <code>user</code> config, which
87 defaults to <code>nobody</code>.  Set the <code>unsafe-perm</code> flag to run scripts with
88 root privileges.</p>
89
90 <h2 id="ENVIRONMENT">ENVIRONMENT</h2>
91
92 <p>Package scripts run in an environment where many pieces of information
93 are made available regarding the setup of npm and the current state of
94 the process.</p>
95
96 <h3 id="path">path</h3>
97
98 <p>If you depend on modules that define executable scripts, like test
99 suites, then those executables will be added to the <code>PATH</code> for
100 executing the scripts.  So, if your package.json has this:</p>
101
102 <pre><code>{ &quot;name&quot; : &quot;foo&quot;
103 , &quot;dependencies&quot; : { &quot;bar&quot; : &quot;0.1.x&quot; }
104 , &quot;scripts&quot;: { &quot;start&quot; : &quot;bar ./test&quot; } }</code></pre>
105
106 <p>then you could run <code>npm start</code> to execute the <code>bar</code> script, which is
107 exported into the <code>node_modules/.bin</code> directory on <code>npm install</code>.</p>
108
109 <h3 id="package-json-vars">package.json vars</h3>
110
111 <p>The package.json fields are tacked onto the <code>npm_package_</code> prefix. So,
112 for instance, if you had <code>{&quot;name&quot;:&quot;foo&quot;, &quot;version&quot;:&quot;1.2.5&quot;}</code> in your
113 package.json file, then your package scripts would have the
114 <code>npm_package_name</code> environment variable set to &quot;foo&quot;, and the
115 <code>npm_package_version</code> set to &quot;1.2.5&quot;</p>
116
117 <h3 id="configuration">configuration</h3>
118
119 <p>Configuration parameters are put in the environment with the
120 <code>npm_config_</code> prefix. For instance, you can view the effective <code>root</code>
121 config by checking the <code>npm_config_root</code> environment variable.</p>
122
123 <h3 id="Special-package-json-config-hash">Special: package.json &quot;config&quot; hash</h3>
124
125 <p>The package.json &quot;config&quot; keys are overwritten in the environment if
126 there is a config param of <code>&lt;name&gt;[@&lt;version&gt;]:&lt;key&gt;</code>.  For example,
127 if the package.json has this:</p>
128
129 <pre><code>{ &quot;name&quot; : &quot;foo&quot;
130 , &quot;config&quot; : { &quot;port&quot; : &quot;8080&quot; }
131 , &quot;scripts&quot; : { &quot;start&quot; : &quot;node server.js&quot; } }</code></pre>
132
133 <p>and the server.js is this:</p>
134
135 <pre><code>http.createServer(...).listen(process.env.npm_package_config_port)</code></pre>
136
137 <p>then the user could change the behavior by doing:</p>
138
139 <pre><code>npm config set foo:port 80</code></pre>
140
141 <h3 id="current-lifecycle-event">current lifecycle event</h3>
142
143 <p>Lastly, the <code>npm_lifecycle_event</code> environment variable is set to
144 whichever stage of the cycle is being executed. So, you could have a
145 single script used for different parts of the process which switches
146 based on what&#39;s currently happening.</p>
147
148 <p>Objects are flattened following this format, so if you had
149 <code>{&quot;scripts&quot;:{&quot;install&quot;:&quot;foo.js&quot;}}</code> in your package.json, then you&#39;d
150 see this in the script:</p>
151
152 <pre><code>process.env.npm_package_scripts_install === &quot;foo.js&quot;</code></pre>
153
154 <h2 id="EXAMPLES">EXAMPLES</h2>
155
156 <p>For example, if your package.json contains this:</p>
157
158 <pre><code>{ &quot;scripts&quot; :
159   { &quot;install&quot; : &quot;scripts/install.js&quot;
160   , &quot;postinstall&quot; : &quot;scripts/install.js&quot;
161   , &quot;uninstall&quot; : &quot;scripts/uninstall.js&quot;
162   }
163 }</code></pre>
164
165 <p>then the <code>scripts/install.js</code> will be called for the install,
166 post-install, stages of the lifecycle, and the <code>scripts/uninstall.js</code>
167 would be called when the package is uninstalled.  Since
168 <code>scripts/install.js</code> is running for three different phases, it would
169 be wise in this case to look at the <code>npm_lifecycle_event</code> environment
170 variable.</p>
171
172 <p>If you want to run a make command, you can do so.  This works just
173 fine:</p>
174
175 <pre><code>{ &quot;scripts&quot; :
176   { &quot;preinstall&quot; : &quot;./configure&quot;
177   , &quot;install&quot; : &quot;make &amp;&amp; make install&quot;
178   , &quot;test&quot; : &quot;make test&quot;
179   }
180 }</code></pre>
181
182 <h2 id="EXITING">EXITING</h2>
183
184 <p>Scripts are run by passing the line as a script argument to <code>sh</code>.</p>
185
186 <p>If the script exits with a code other than 0, then this will abort the
187 process.</p>
188
189 <p>Note that these script files don&#39;t have to be nodejs or even
190 javascript programs. They just have to be some kind of executable
191 file.</p>
192
193 <h2 id="HOOK-SCRIPTS">HOOK SCRIPTS</h2>
194
195 <p>If you want to run a specific script at a specific lifecycle event for
196 ALL packages, then you can use a hook script.</p>
197
198 <p>Place an executable file at <code>node_modules/.hooks/{eventname}</code>, and
199 it&#39;ll get run for all packages when they are going through that point
200 in the package lifecycle for any packages installed in that root.</p>
201
202 <p>Hook scripts are run exactly the same way as package.json scripts.
203 That is, they are in a separate child process, with the env described
204 above.</p>
205
206 <h2 id="BEST-PRACTICES">BEST PRACTICES</h2>
207
208 <ul><li>Don&#39;t exit with a non-zero error code unless you <em>really</em> mean it.
209 Except for uninstall scripts, this will cause the npm action to
210 fail, and potentially be rolled back.  If the failure is minor or
211 only will prevent some optional features, then it&#39;s better to just
212 print a warning and exit successfully.</li><li>Try not to use scripts to do what npm can do for you.  Read through
213 <code><a href="../files/package.json.html">package.json(5)</a></code> to see all the things that you can specify and enable
214 by simply describing your package appropriately.  In general, this
215 will lead to a more robust and consistent state.</li><li>Inspect the env to determine where to put things.  For instance, if
216 the <code>npm_config_binroot</code> environ is set to <code>/home/user/bin</code>, then
217 don&#39;t try to install executables into <code>/usr/local/bin</code>.  The user
218 probably set it up that way for a reason.</li><li>Don&#39;t prefix your script commands with &quot;sudo&quot;.  If root permissions
219 are required for some reason, then it&#39;ll fail with that error, and
220 the user will sudo the npm command in question.</li></ul>
221
222 <h2 id="SEE-ALSO">SEE ALSO</h2>
223
224 <ul><li><a href="../cli/npm-run-script.html">npm-run-script(1)</a></li><li><a href="../files/package.json.html">package.json(5)</a></li><li><a href="../misc/npm-developers.html">npm-developers(7)</a></li><li><a href="../cli/npm-install.html">npm-install(1)</a></li></ul>
225 </div>
226 <p id="footer">npm-scripts &mdash; npm@1.3.17</p>
227 <script>
228 ;(function () {
229 var wrapper = document.getElementById("wrapper")
230 var els = Array.prototype.slice.call(wrapper.getElementsByTagName("*"), 0)
231   .filter(function (el) {
232     return el.parentNode === wrapper
233         && el.tagName.match(/H[1-6]/)
234         && el.id
235   })
236 var l = 2
237   , toc = document.createElement("ul")
238 toc.innerHTML = els.map(function (el) {
239   var i = el.tagName.charAt(1)
240     , out = ""
241   while (i > l) {
242     out += "<ul>"
243     l ++
244   }
245   while (i < l) {
246     out += "</ul>"
247     l --
248   }
249   out += "<li><a href='#" + el.id + "'>" +
250     ( el.innerText || el.text || el.innerHTML)
251     + "</a>"
252   return out
253 }).join("\n")
254 toc.id = "toc"
255 document.body.appendChild(toc)
256 })()
257 </script>