Skip to content
Permalink
Browse files
fix(docs): update scripts docs
The lifecycle events section was very out of date, and lots
of other cleanup needed to happen too

PR-URL: #2690
Credit: @wraithgar
Close: #2690
Reviewed-by: @ruyadorno
  • Loading branch information
wraithgar authored and ruyadorno committed Mar 4, 2021
1 parent 0c881fc commit c8b73db82f0f2445c20a0a64110586253accd66b
Showing with 139 additions and 52 deletions.
  1. +139 −52 docs/content/using-npm/scripts.md
@@ -6,11 +6,19 @@ description: How npm handles the "scripts" field

### Description

The `"scripts"` property of your `package.json` file supports a number of built-in scripts and their preset life cycle events as well as arbitrary scripts. These all can be executed by running `npm run-script <stage>` or `npm run <stage>` for short. *Pre* and *post* commands with matching names will be run for those as well (e.g. `premyscript`, `myscript`, `postmyscript`). Scripts from dependencies can be run with `npm explore <pkg> -- npm run <stage>`.
The `"scripts"` property of your `package.json` file supports a number
of built-in scripts and their preset life cycle events as well as
arbitrary scripts. These all can be executed by running `npm run-script
<stage>` or `npm run <stage>` for short. *Pre* and *post* commands with
matching names will be run for those as well (e.g. `premyscript`,
`myscript`, `postmyscript`). Scripts from dependencies can be run with
`npm explore <pkg> -- npm run <stage>`.

### Pre & Post Scripts

To create "pre" or "post" scripts for any scripts defined in the `"scripts"` section of the `package.json`, simply create another script *with a matching name* and add "pre" or "post" to the beginning of them.
To create "pre" or "post" scripts for any scripts defined in the
`"scripts"` section of the `package.json`, simply create another script
*with a matching name* and add "pre" or "post" to the beginning of them.

```json
{
@@ -22,20 +30,35 @@ To create "pre" or "post" scripts for any scripts defined in the `"scripts"` sec
}
```

In this example `npm run compress` would execute these scripts as
described.

### Life Cycle Scripts

There are some special life cycle scripts that happen only in certain situations. These scripts happen in addition to the "pre" and "post" script.
There are some special life cycle scripts that happen only in certain
situations. These scripts happen in addition to the `pre<event>`, `post<event>`, and
`<event>` scripts.

* `prepare`, `prepublish`, `prepublishOnly`, `prepack`, `postpack`

**prepare** (since `npm@4.0.0`)
* Runs any time before the package is packed, i.e. during `npm publish`
and `npm pack`
* Runs BEFORE the package is packed
* Runs BEFORE the package is published
* Runs on local `npm install` without any arguments
* Run AFTER `prepublish`, but BEFORE `prepublishOnly`
* NOTE: If a package being installed through git contains a `prepare` script, its `dependencies` and `devDependencies` will be installed, and the prepare script will be run, before the package is packaged and installed.

* NOTE: If a package being installed through git contains a `prepare`
script, its `dependencies` and `devDependencies` will be installed, and
the prepare script will be run, before the package is packaged and
installed.

* As of `npm@7` these scripts run in the background

**prepublish** (DEPRECATED)
* Same as `prepare`
* Does not run during `npm publish`, but does run during `npm ci`
and `npm install`. See below for more info.

**prepublishOnly**
* Runs BEFORE the package is prepared and packed, ONLY on `npm publish`.
@@ -45,7 +68,7 @@ There are some special life cycle scripts that happen only in certain situations
* NOTE: "`npm run pack`" is NOT the same as "`npm pack`". "`npm run pack`" is an arbitrary user defined script name, where as, "`npm pack`" is a CLI defined command.

**postpack**
* Runs AFTER the tarball has been generated and moved to its final destination.
* Runs AFTER the tarball has been generated but before it is moved to its final destination (if at all, publish does not save the tarball locally)

#### Prepare and Prepublish

@@ -74,51 +97,116 @@ The advantage of doing these things at `prepublish` time is that they can be don

### Life Cycle Operation Order

#### [`npm publish`](/commands/npm-publish)
#### [`npm cache add`](/commands/npm-cache)

* `prepublishOnly`
* `prepare`

#### [`npm ci`](/commands/npm-ci)

* `preinstall`
* `install`
* `postinstall`
* `prepublish`
* `publish`
* `postpublish`
* `preprepare`
* `prepare`
* `postprepare`

These all run after the actual installation of modules into
`node_modules`, in order, with no internal actions happening in between

#### [`npm diff`](/commands/npm-diff)

* `prepare`

#### [`npm env`](/commands/npm-env)

* `env` (You can override the default behavior of `npm env` by defining
a custom `env` entry in your `scripts` object)

#### [`npm install`](/commands/npm-install)

These also run when you run `npm install -g <pkg-name>`

* `preinstall`
* `install`
* `postinstall`
* `prepublish`
* `preprepare`
* `prepare`
* `postprepare`

If there is a `binding.gyp` file in the root of your package and you
haven't defined your own `install` or `preinstall` scripts, npm will
default the `install` command to compile using node-gyp via `node-gyp
rebuild`

These are run from the scripts of `<pkg-name>`

#### [`npm pack`](/commands/npm-pack)

* `prepack`
* `prepare`
* `postpack`

#### [`npm install`](/commands/npm-install)
#### [`npm publish`](/commands/npm-publish)

* `prepublishOnly`
* `prepack`
* `prepare`
* `postpack`
* `publish`
* `postpublish`

`prepare` will not run during `--dry-run`

#### [`npm rebuild`](/commands/npm-rebuild)

* `preinstall`
* `install`
* `postinstall`
* `prepare`

Also triggers
`prepare` is only run if the current directory is a symlink (e.g. with
linked packages)

* `prepublish` (when on local)
* `prepare` (when on local or workspaces)
#### [`npm restart`](/commands/npm-restart)

#### [`npm start`](/commands/npm-start)
If there is a `restart` script defined, these events are run, otherwise
`stop` and `start` are both run if present, including their `pre` and
`post` iterations)

* `prerestart`
* `restart`
* `postrestart`

`npm run start` has an `npm start` shorthand.
#### [`npm run <user defined>`](/commands/npm-run)

* `pre<user-defined>`
* `<user-defined>`
* `post<user-defined>`

#### [`npm start`](/commands/npm-start)

* `prestart`
* `start`
* `poststart`

### Default Values
npm will default some script values based on package contents.
If there is a `server.js` file in the root of your package, then npm
will default the `start` command to `node server.js`. `prestart` and
`poststart` will still run in this case.

#### [`npm stop`](/commands/npm-stop)

* `"start": "node server.js"`:
* `prestop`
* `stop`
* `poststop`

If there is a `server.js` file in the root of your package, then npm
will default the `start` command to `node server.js`.
#### [`npm test`](/commands/npm-test)

* `"install": "node-gyp rebuild"`:
* `pretest`
* `test`
* `posttest`

If there is a `binding.gyp` file in the root of your package and you
haven't defined your own `install` or `preinstall` scripts, npm will
default the `install` command to compile using node-gyp.

### User

@@ -131,22 +219,21 @@ 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.


#### path

If you depend on modules that define executable scripts, like test
suites, then those executables will be added to the `PATH` for
executing the scripts. So, if your package.json has this:

```json
{
"name" : "foo",
"dependencies" : {
"bar" : "0.1.x"
},
"scripts": {
"start" : "bar ./test"
}
{
"name" : "foo",
"dependencies" : {
"bar" : "0.1.x"
},
"scripts": {
"start" : "bar ./test"
}
}
```

@@ -159,8 +246,8 @@ The package.json fields are tacked onto the `npm_package_` prefix. So,
for instance, if you had `{"name":"foo", "version":"1.2.5"}` in your
package.json file, then your package scripts would have the
`npm_package_name` environment variable set to "foo", and the
`npm_package_version` set to "1.2.5". You can access these variables
in your code with `process.env.npm_package_name` and
`npm_package_version` set to "1.2.5". You can access these variables
in your code with `process.env.npm_package_name` and
`process.env.npm_package_version`, and so on for other fields.

#### configuration
@@ -176,14 +263,14 @@ there is a config param of `<name>[@<version>]:<key>`. For example,
if the package.json has this:

```json
{
"name" : "foo",
"config" : {
"port" : "8080"
},
"scripts" : {
"start" : "node server.js"
}
{
"name" : "foo",
"config" : {
"port" : "8080"
},
"scripts" : {
"start" : "node server.js"
}
}
```

@@ -219,10 +306,10 @@ process.env.npm_package_scripts_install === "foo.js"
For example, if your package.json contains this:

```json
{
"scripts" : {
"install" : "scripts/install.js",
"postinstall" : "scripts/postinstall.js",
{
"scripts" : {
"install" : "scripts/install.js",
"postinstall" : "scripts/postinstall.js",
"uninstall" : "scripts/uninstall.js"
}
}
@@ -239,10 +326,10 @@ If you want to run a make command, you can do so. This works just
fine:

```json
{
"scripts" : {
"preinstall" : "./configure",
"install" : "make && make install",
{
"scripts" : {
"preinstall" : "./configure",
"install" : "make && make install",
"test" : "make test"
}
}

0 comments on commit c8b73db

Please sign in to comment.