1 | # @npmcli/run-script
|
---|
2 |
|
---|
3 | Run a lifecycle script for a package (descendant of npm-lifecycle)
|
---|
4 |
|
---|
5 | ## USAGE
|
---|
6 |
|
---|
7 | ```js
|
---|
8 | const runScript = require('@npmcli/run-script')
|
---|
9 |
|
---|
10 | runScript({
|
---|
11 | // required, the script to run
|
---|
12 | event: 'install',
|
---|
13 |
|
---|
14 | // extra args to pass to the command, defaults to []
|
---|
15 | args: [],
|
---|
16 |
|
---|
17 | // required, the folder where the package lives
|
---|
18 | path: '/path/to/package/folder',
|
---|
19 |
|
---|
20 | // optional, defaults to /bin/sh on unix, or cmd.exe on windows
|
---|
21 | scriptShell: '/bin/bash',
|
---|
22 |
|
---|
23 | // optional, defaults to false
|
---|
24 | // return stdout and stderr as strings rather than buffers
|
---|
25 | stdioString: true,
|
---|
26 |
|
---|
27 | // optional, additional environment variables to add
|
---|
28 | // note that process.env IS inherited by default
|
---|
29 | // Always set:
|
---|
30 | // - npm_package_json The package.json file in the folder
|
---|
31 | // - npm_lifecycle_event The event that this is being run for
|
---|
32 | // - npm_lifecycle_script The script being run
|
---|
33 | // The fields described in https://github.com/npm/rfcs/pull/183
|
---|
34 | env: {
|
---|
35 | npm_package_from: 'foo@bar',
|
---|
36 | npm_package_resolved: 'https://registry.npmjs.org/foo/-/foo-1.2.3.tgz',
|
---|
37 | npm_package_integrity: 'sha512-foobarbaz',
|
---|
38 | },
|
---|
39 |
|
---|
40 | // defaults to 'pipe'. Can also pass an array like you would to node's
|
---|
41 | // exec or spawn functions. Note that if it's anything other than
|
---|
42 | // 'pipe' then the stdout/stderr values on the result will be missing.
|
---|
43 | // npm cli sets this to 'inherit' for explicit run-scripts (test, etc.)
|
---|
44 | // but leaves it as 'pipe' for install scripts that run in parallel.
|
---|
45 | stdio: 'inherit',
|
---|
46 |
|
---|
47 | // print the package id and script, and the command to be run, like:
|
---|
48 | // > somepackage@1.2.3 postinstall
|
---|
49 | // > make all-the-things
|
---|
50 | // Defaults true when stdio:'inherit', otherwise suppressed
|
---|
51 | banner: true,
|
---|
52 | })
|
---|
53 | .then(({ code, signal, stdout, stderr, pkgid, path, event, script }) => {
|
---|
54 | // do something with the results
|
---|
55 | })
|
---|
56 | .catch(er => {
|
---|
57 | // command did not work.
|
---|
58 | // er is decorated with:
|
---|
59 | // - code
|
---|
60 | // - signal
|
---|
61 | // - stdout
|
---|
62 | // - stderr
|
---|
63 | // - path
|
---|
64 | // - pkgid (name@version string)
|
---|
65 | // - event
|
---|
66 | // - script
|
---|
67 | })
|
---|
68 | ```
|
---|
69 |
|
---|
70 | ## API
|
---|
71 |
|
---|
72 | Call the exported `runScript` function with an options object.
|
---|
73 |
|
---|
74 | Returns a promise that resolves to the result of the execution. Promise
|
---|
75 | rejects if the execution fails (exits non-zero) or has any other error.
|
---|
76 | Rejected errors are decorated with the same values as the result object.
|
---|
77 |
|
---|
78 | If the stdio options mean that it'll have a piped stdin, then the stdin is
|
---|
79 | ended immediately on the child process. If stdin is shared with the parent
|
---|
80 | terminal, then it is up to the user to end it, of course.
|
---|
81 |
|
---|
82 | ### Results
|
---|
83 |
|
---|
84 | - `code` Process exit code
|
---|
85 | - `signal` Process exit signal
|
---|
86 | - `stdout` stdout data (Buffer, or String when `stdioString` set to true)
|
---|
87 | - `stderr` stderr data (Buffer, or String when `stdioString` set to true)
|
---|
88 | - `path` Path to the package executing its script
|
---|
89 | - `event` Lifecycle event being run
|
---|
90 | - `script` Command being run
|
---|
91 |
|
---|
92 | ### Options
|
---|
93 |
|
---|
94 | - `path` Required. The path to the package having its script run.
|
---|
95 | - `event` Required. The event being executed.
|
---|
96 | - `args` Optional, default `[]`. Extra arguments to pass to the script.
|
---|
97 | - `env` Optional, object of fields to add to the environment of the
|
---|
98 | subprocess. Note that process.env IS inherited by default These are
|
---|
99 | always set:
|
---|
100 | - `npm_package_json` The package.json file in the folder
|
---|
101 | - `npm_lifecycle_event` The event that this is being run for
|
---|
102 | - `npm_lifecycle_script` The script being run
|
---|
103 | - The `package.json` fields described in
|
---|
104 | [RFC183](https://github.com/npm/rfcs/pull/183/files).
|
---|
105 | - `scriptShell` Optional, defaults to `/bin/sh` on Unix, defaults to
|
---|
106 | `env.ComSpec` or `cmd` on Windows. Custom script to use to execute the
|
---|
107 | command.
|
---|
108 | - `stdio` Optional, defaults to `'pipe'`. The same as the `stdio` argument
|
---|
109 | passed to `child_process` functions in Node.js. Note that if a stdio
|
---|
110 | output is set to anything other than `pipe`, it will not be present in
|
---|
111 | the result/error object.
|
---|
112 | - `cmd` Optional. Override the script from the `package.json` with
|
---|
113 | something else, which will be run in an otherwise matching environment.
|
---|
114 | - `stdioString` Optional, defaults to `false`. Return string values for
|
---|
115 | `stderr` and `stdout` rather than Buffers.
|
---|
116 | - `banner` Optional, defaults to `true`. If the `stdio` option is set to
|
---|
117 | `'inherit'`, then print a banner with the package name and version, event
|
---|
118 | name, and script command to be run. Set explicitly to `false` to disable
|
---|
119 | for inherited stdio.
|
---|
120 |
|
---|
121 | Note that this does _not_ run pre-event and post-event scripts. The
|
---|
122 | caller has to manage that process themselves.
|
---|
123 |
|
---|
124 | ## Differences from [npm-lifecycle](https://github.com/npm/npm-lifecycle)
|
---|
125 |
|
---|
126 | This is an implementation to satisfy [RFC
|
---|
127 | 90](https://github.com/npm/rfcs/pull/90), [RFC
|
---|
128 | 77](https://github.com/npm/rfcs/pull/77), and [RFC
|
---|
129 | 73](https://github.com/npm/rfcs/pull/73).
|
---|
130 |
|
---|
131 | Apart from those behavior changes in npm v7, this is also just refresh of
|
---|
132 | the codebase, with modern coding techniques and better test coverage.
|
---|
133 |
|
---|
134 | Functionally, this means:
|
---|
135 |
|
---|
136 | - Output is not dumped to the top level process's stdio by default.
|
---|
137 | - Less stuff is put into the environment.
|
---|
138 | - It is not opinionated about logging. (So, at least with the logging
|
---|
139 | framework in npm v7.0 and before, the caller has to call
|
---|
140 | `log.disableProgress()` and `log.enableProgress()` at the appropriate
|
---|
141 | times, if necessary.)
|
---|
142 | - The directory containing the `node` executable is _never_ added to the
|
---|
143 | `PATH` environment variable. (Ie, `--scripts-prepend-node-path` is
|
---|
144 | effectively always set to `false`.) Doing so causes more unintended side
|
---|
145 | effects than it ever prevented.
|
---|
146 | - Hook scripts are not run by this module. If the caller wishes to run
|
---|
147 | hook scripts, then they can override the default package script with an
|
---|
148 | explicit `cmd` option pointing to the `node_modules/.hook/${event}`
|
---|
149 | script.
|
---|