Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@npmcli/run-script

npm25.2mISC9.0.2

Run a lifecycle script for a package (descendant of npm-lifecycle)

readme

@npmcli/run-script

Run a lifecycle script for a package (descendant of npm-lifecycle)

USAGE

const runScript = require('@npmcli/run-script')

runScript({
  // required, the script to run
  event: 'install',

  // extra args to pass to the command, defaults to []
  args: [],

  // required, the folder where the package lives
  path: '/path/to/package/folder',

  // optional, these paths will be put at the beginning of `$PATH`, even
  // after run-script adds the node_modules/.bin folder(s) from
  // `process.cwd()`. This is for commands like `npm init`, `npm exec`,
  // and `npx` to make sure manually installed  packages come before
  // anything that happens to be in the tree in `process.cwd()`.
  binPaths: [
    '/path/to/npx/node_modules/.bin',
    '/path/to/npm/prefix/node_modules/.bin',
  ],

  // optional, defaults to /bin/sh on unix, or cmd.exe on windows
  scriptShell: '/bin/bash',

  // optional, passed directly to `@npmcli/promise-spawn` which defaults it to true
  // return stdout and stderr as strings rather than buffers
  stdioString: false,

  // optional, additional environment variables to add
  // note that process.env IS inherited by default
  // Always set:
  // - npm_package_json The package.json file in the folder
  // - npm_lifecycle_event The event that this is being run for
  // - npm_lifecycle_script The script being run
  // The fields described in https://github.com/npm/rfcs/pull/183
  env: {
    npm_package_from: 'foo@bar',
    npm_package_resolved: 'https://registry.npmjs.org/foo/-/foo-1.2.3.tgz',
    npm_package_integrity: 'sha512-foobarbaz',
  },

  // defaults to 'pipe'.  Can also pass an array like you would to node's
  // exec or spawn functions.  Note that if it's anything other than
  // 'pipe' then the stdout/stderr values on the result will be missing.
  // npm cli sets this to 'inherit' for explicit run-scripts (test, etc.)
  // but leaves it as 'pipe' for install scripts that run in parallel.
  stdio: 'inherit',

  // print the package id and script, and the command to be run, like:
  // > somepackage@1.2.3 postinstall
  // > make all-the-things
})
  .then(({ code, signal, stdout, stderr, pkgid, path, event, script }) => {
    // do something with the results
  })
  .catch(er => {
    // command did not work.
    // er is decorated with:
    // - code
    // - signal
    // - stdout
    // - stderr
    // - path
    // - pkgid (name@version string)
    // - event
    // - script
  })

API

Call the exported runScript function with an options object.

Returns a promise that resolves to the result of the execution. Promise rejects if the execution fails (exits non-zero) or has any other error. Rejected errors are decorated with the same values as the result object.

If the stdio options mean that it'll have a piped stdin, then the stdin is ended immediately on the child process. If stdin is shared with the parent terminal, then it is up to the user to end it, of course.

Results

  • code Process exit code
  • signal Process exit signal
  • stdout stdout data (Buffer, or String when stdioString set to true)
  • stderr stderr data (Buffer, or String when stdioString set to true)
  • path Path to the package executing its script
  • event Lifecycle event being run
  • script Command being run

If stdio is inherit this package will emit a banner with the package name and version, event name, and script command to be run, and send it to proc-log.output.standard. Consuming libraries can decide whether or not to display this.

Options

  • path Required. The path to the package having its script run.
  • event Required. The event being executed.
  • args Optional, default []. Extra arguments to pass to the script.
  • env Optional, object of fields to add to the environment of the subprocess. Note that process.env IS inherited by default These are always set:
    • npm_package_json The package.json file in the folder
    • npm_lifecycle_event The event that this is being run for
    • npm_lifecycle_script The script being run
    • The package.json fields described in RFC183.
  • scriptShell Optional, defaults to /bin/sh on Unix, defaults to env.ComSpec or cmd on Windows. Custom script to use to execute the command.
  • stdio Optional, defaults to 'pipe'. The same as the stdio argument passed to child_process functions in Node.js. Note that if a stdio output is set to anything other than pipe, it will not be present in the result/error object.
  • cmd Optional. Override the script from the package.json with something else, which will be run in an otherwise matching environment.
  • stdioString Optional, passed directly to @npmcli/promise-spawn which defaults it to true. Return string values for stderr and stdout rather than Buffers.

Note that this does not run pre-event and post-event scripts. The caller has to manage that process themselves.

Differences from npm-lifecycle

This is an implementation to satisfy RFC 90, RFC 77, and RFC 73.

Apart from those behavior changes in npm v7, this is also just refresh of the codebase, with modern coding techniques and better test coverage.

Functionally, this means:

  • Output is not dumped to the top level process's stdio by default.
  • Less stuff is put into the environment.
  • It is not opinionated about logging. (So, at least with the logging framework in npm v7.0 and before, the caller has to call log.disableProgress() and log.enableProgress() at the appropriate times, if necessary.)
  • The directory containing the node executable is never added to the PATH environment variable. (Ie, --scripts-prepend-node-path is effectively always set to false.) Doing so causes more unintended side effects than it ever prevented.
  • Hook scripts are not run by this module. If the caller wishes to run hook scripts, then they can override the default package script with an explicit cmd option pointing to the node_modules/.hook/${event} script.

Escaping

In order to ensure that arguments are handled consistently, this module writes a temporary script file containing the command as it exists in the package.json, followed by the user supplied arguments having been escaped to ensure they are processed as literal strings. We then instruct the shell to execute the script file, and when the process exits we remove the temporary file.

In Windows, when the shell is cmd, and when the initial command in the script is a known batch file (i.e. something.cmd) we double escape additional arguments so that the shim scripts npm installs work correctly.

The actual implementation of the escaping is in lib/escape.js.

changelog

Changelog

9.0.2 (2024-12-04)

Dependencies

9.0.1 (2024-10-02)

Dependencies

9.0.0 (2024-09-26)

⚠️ BREAKING CHANGES

  • @npmcli/run-script now supports node ^18.17.0 || >=20.5.0

    Bug Fixes

  • 7ff5e68 #218 align to npm 10 node engine range (@reggi)

    Dependencies

  • 585d1ef #218 `proc-log@5.0.0`
  • bfc5bf1 #218 @npmcli/promise-spawn@8.0.0
  • 26da68c #218 @npmcli/node-gyp@4.0.0

    Chores

  • e49feef #218 run template-oss-apply (@reggi)
  • 1755bf8 #213 bump @npmcli/eslint-config from 4.0.5 to 5.0.0 (@dependabot[bot])
  • 97e60c5 #203 bump @npmcli/template-oss to 4.22.0 (@lukekarrys)
  • 27bf80f #214 postinstall for dependabot template-oss PR (@hashtagchris)
  • 8ad1a6c #214 bump @npmcli/template-oss from 4.23.1 to 4.23.3 (@dependabot[bot])

8.1.0 (2024-04-29)

Features

  • afb3db4 #202 call input start/end around spawned process (#202) (@lukekarrys)

Chores

  • 8417f1b #200 postinstall for dependabot template-oss PR (@lukekarrys)
  • 5d16957 #200 bump @npmcli/template-oss from 4.21.3 to 4.21.4 (@dependabot[bot])

8.0.0 (2024-04-12)

⚠️ BREAKING CHANGES

  • The existing banner is now emitted using proc-log instead of console.log. It is always emitted. Consuming libraries can decide under which situations to show the banner.

Features

Dependencies

7.0.4 (2024-01-22)

Bug Fixes

  • 7ebc853 #194 envs: revert behavior of array in npm config (#194) (@wraithgar, @siemhesda)
  • bf5f419 #192 code formatting (@wraithgar)
  • b6f7f93 #192 remove unreachable code path (@wraithgar)
  • 865d556 #192 remove is-windows test fixture code from module (@wraithgar)
  • c47a91a #192 update code to use @npmcli/run-script (@wraithgar)

Dependencies

Chores

7.0.3 (2024-01-03)

Bug Fixes

  • 089eefb Revert Signal Handling Regression (#188) (@wiktor-obrebski)

Chores

  • 8a0443b #187 postinstall for dependabot template-oss PR (@lukekarrys)
  • ccf6eb6 #187 bump @npmcli/template-oss from 4.21.1 to 4.21.3 (@dependabot[bot])
  • 92c4354 #184 postinstall for dependabot template-oss PR (@lukekarrys)
  • 1f5fd9a #184 bump @npmcli/template-oss from 4.19.0 to 4.21.1 (@dependabot[bot])

7.0.2 (2023-10-29)

Dependencies

7.0.1 (2023-08-30)

Dependencies

  • f61fd84 #159 bump @npmcli/promise-spawn from 6.0.2 to 7.0.0

7.0.0 (2023-08-30)

⚠️ BREAKING CHANGES

  • support for node 14 has been removed

Bug Fixes

Dependencies

6.0.2 (2023-05-08)

Bug Fixes

  • 545f3be #142 handle signals more correctly (#142) (@nlf)

Documentation

  • 581be58 #141 fix syntax in example (#141) (@kas-elvirov)

6.0.1 (2023-04-27)

Bug Fixes

  • 3a8f085 #147 remove unused dependency on minipass (#147) (@nlf)

6.0.0 (2022-11-02)

⚠️ BREAKING CHANGES

  • stdioString is no longer set to false by default. Instead it is not set and passed directory to @npmcli/promise-spawn which defaults it to true.

Features

  • 34ecf46 #134 dont set a default for stdioString (@lukekarrys)

5.1.1 (2022-11-01)

Dependencies

5.1.0 (2022-11-01)

Features

  • 45f2301 let @npmcli/promise-spawn do the escaping (@nlf)

Dependencies

5.0.1 (2022-10-26)

Dependencies

  • 1bfadcb #127 bump @npmcli/promise-spawn from 4.0.0 to 5.0.0 (#127)

5.0.0 (2022-10-14)

⚠️ BREAKING CHANGES

  • @npmcli/run-script is now compatible with the following semver range for node: ^14.17.0 || ^16.13.0 || >=18.0.0

Features

  • 891cb2a #113 postinstall for dependabot template-oss PR (@lukekarrys)

Dependencies

  • d41405e #121 bump @npmcli/node-gyp from 2.0.0 to 3.0.0 (#121)
  • 5fc0e27 #123 bump @npmcli/promise-spawn from 3.0.0 to 4.0.0
  • 132b84b #120 bump read-package-json-fast from 2.0.3 to 3.0.0

4.2.1 (2022-08-09)

Bug Fixes

4.2.0 (2022-08-01)

Features

4.1.7 (2022-07-12)

Bug Fixes

  • correctly translate paths when using bash in windows (#96) (756ff56)

4.1.6 (2022-07-12)

Bug Fixes

  • tighten up the character set that will be removed (#93) (d510209)
  • unique filename for temporary script files (#95) (9f93025)

4.1.5 (2022-06-28)

Bug Fixes

4.1.4 (2022-06-27)

Bug Fixes

  • remove invalid characters from filename (#86) (2354d06)

4.1.3 (2022-06-23)

Bug Fixes

  • escape spaces in cmd scripts too (#84) (0bca5be)

4.1.2 (2022-06-22)

Bug Fixes

  • remove extraneous space when no additional args are passed (#82) (9e09bab)

4.1.1 (2022-06-22)

Bug Fixes

  • correctly double escape when script runs a known .cmd file (#80) (0f613cd)

4.1.0 (2022-06-21)

Features

  • write scripts to a file and run that instead of passing scripts as a single string (24c5165)

Bug Fixes

  • cleanup temp script after running (7963ab5)

4.0.0 (2022-06-02)

⚠ BREAKING CHANGES

  • changes engines support to ^12.22 || ^14.13 || >=16

Dependencies

  • bump node-gyp from 8.4.1 to 9.0.0 (#76) (e62e3a5)

3.0.3 (2022-05-25)

Dependencies

3.0.2 (2022-04-05)

Dependencies

  • bump @npmcli/node-gyp from 1.0.3 to 2.0.0 (#65) (731240d)
  • bump @npmcli/promise-spawn from 1.3.2 to 3.0.0 (#67) (afcab18)

3.0.1 (2022-03-02)

Dependencies

  • bump node-gyp from 8.4.1 to 9.0.0 (#52) (148ce21)

3.0.0 (2022-02-23)

⚠ BREAKING CHANGES

  • this will drop support for node10 and non-LTS versions of node12 and node14

Features

Dependencies

  • update @npmcli/node-gyp requirement from ^1.0.2 to ^1.0.3 (#47) (cdd27cc)
  • update node-gyp requirement from ^8.2.0 to ^8.4.1 (#45) (1575902)
  • update read-package-json-fast requirement from ^2.0.1 to ^2.0.3 (#48) (7747c5a)