npm scripts usage guide
Node development is inseparable from npm, and the scripting function is one of the most powerful and commonly used functions of npm.
This article describes how to use npm scripts.
1. What is an npm script?
npm allows you to
package.json
use
scripts
fields to define script commands
in the
file
.
{ // ... "scripts": { "build": "node build.js" } }
The above code is
package.json
a fragment
of the
file, and the
scripts
field
inside
is an object.
Each of its attributes corresponds to a script.
For example,
build
the script corresponding to the command is
node build.js
.
Use the
npm run
command
under the command line to
execute this script.
$ npm run build # 等同于执行 $ node build.js
These
package.json
scripts
defined in
it are called npm scripts.
It has many advantages.
- The relevant scripts of the project can be concentrated in one place.
- Script commands of different projects can have the same external interface as long as they have the same function. The user does not need to know how to test your project, just run it
npm run test
.- Many auxiliary functions provided by npm can be used.
To view all the npm script commands of the current project, you can use the
npm run
command
without any parameters
.
$ npm run
2. Principle
The principle of npm scripts is very simple.
Whenever it is executed
npm run
, it will automatically create a new Shell, and execute the specified script commands in this Shell.
Therefore, as long as it is a command that can be run by Shell (usually Bash), it can be written in an npm script.
What’s more special is that the
npm run
newly created Shell will add the
node_modules/.bin
subdirectories of the
current directory
to the
PATH
variable, and after the execution is over, the
PATH
variable will be restored to its original state.
This means that
node_modules/.bin
all scripts
in the
subdirectories of the
current directory
can be called directly by the script name without adding a path.
For example, if there is Mocha in the dependency of the current project, just write
mocha test
it
directly
.
"test": "mocha test"
Instead of writing as follows.
"test": "./node_modules/.bin/mocha test"
Since the only requirement of an npm script is that it can be executed in the Shell, it is not necessarily a Node script, any executable file can be written in it.
The exit code of the npm script also complies with the shell script rules.
If the exit code is not
0
, npm considers the script execution failed.
Three, wildcard
Since npm scripts are Shell scripts, Shell wildcards can be used.
"lint": "jshint *.js" "lint": "jshint **/*.js"
In the above code, it
*
represents any file name and
**
any subdirectory at any level.
If you want to pass wildcards into the original command to prevent it from being escaped by the Shell, you must escape the asterisk.
"test": "tap test/\*.js"
Four, transfer parameters
To pass parameters to the npm script, use the
--
markup.
"lint": "jshint **.js"
To
npm run lint
pass parameters
to the above
command, it must be written as follows.
$ npm run lint -- --reporter checkstyle > checkstyle.xml
You can also
package.json
encapsulate a command inside.
"lint": "jshint **.js", "lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"
Five, execution order
If you need to perform multiple tasks in the npm script, you need to clarify the order of their execution.
If it is parallel execution (that is, simultaneous parallel execution),
&
symbols
can be used
.
$ npm run script1.js & npm run script2.js
If it is a secondary execution (that is, only the previous task is successful, the next task is executed), you can use the
&&
symbol.
$ npm run script1.js && npm run script2.js
These two symbols are functions of Bash. In addition, you can also use node’s task management modules: script-runner , npm-run-all , redrun .
Six, the default value
Generally speaking, npm scripts are provided by users. However, npm provides default values for both scripts. In other words, these two scripts can be used directly without definition.
"start": "node server.js", "install": "node-gyp rebuild"
In the above code,
npm run start
the default value is
node server.js
that
server.js
the script
exists in
the
root directory of the project
;
npm run install
the default value is
node-gyp rebuild
that there are
binding.gyp
files in the
root directory of the project
.
Seven, hook
npm script
pre
and
post
two hooks.
For example,
build
the hook of the script command is
prebuild
and
postbuild
.
"prebuild": "echo I run before the build script", "build": "cross-env NODE_ENV=production webpack", "postbuild": "echo I run after the build script"
When the user executes
npm run build
it, it will automatically execute in the following order.
npm run prebuild && npm run build && npm run postbuild
Therefore, in these two hooks, some preparatory work and clean-up work can be completed. Below is an example.
"clean": "rimraf ./dist && mkdir dist", "prebuild": "npm run clean", "build": "cross-env NODE_ENV=production webpack"
npm provides the following hooks by default.
- prepublish, postpublish
- preinstall, postinstall
- preuninstall, postuninstall
- preversion, postversion
- pretest, posttest
- prestop, poststop
- prestart, poststart
- prerestart, postrestart
Custom script commands can also be added
pre
and
post
hooks.
For example,
myscript
this script commands, but also
premyscript
and
postmyscript
hooks.
However, a double
pre
and
post
invalid, for example,
prepretest
and
postposttest
is not valid.
npm provide a
npm_lifecycle_event
variable, returns the name of the currently running script, such as
pretest
,
test
,
posttest
and so on.
Therefore, you can use this variable to
npm scripts
write codes
for different
commands
in the same script file
.
Please see the example below.
const TARGET = process.env.npm_lifecycle_event; if (TARGET === 'test') { console.log(`Running the test task!`); } if (TARGET === 'pretest') { console.log(`Running the pretest task!`); } if (TARGET === 'posttest') { console.log(`Running the posttest task!`); }
Note that
prepublish
this hook will not only run before the
npm publish
command, but also before the command
npm install
(without any parameters).
This behavior is easy to confuse users, so npm 4 introduces a new hook
prepare
, the behavior is equivalent
prepublish
, and starting from npm 5, it
prepublish
will only
npm publish
run before the command.
8. Short form
There are abbreviations for the four commonly used npm scripts.
npm start
Yesnpm run start
npm stop
npm run stop
Shorthand for yesnpm test
npm run test
Shorthand for yesnpm restart
npm run stop && npm run restart && npm run start
Shorthand for yes
npm start
,
npm stop
And
npm restart
are better understood, but
npm restart
is a complex command, the script actually executes three commands:
stop
,
restart
,
start
.
The specific execution sequence is as follows.
- prerestart
- prestop
- stop
- poststop
- restart
- prestart
- start
- poststart
- postrestart
Nine, variables
A very powerful feature of npm scripts is that they can use npm’s internal variables.
First of all, through the
npm_package_
prefix, the npm script can get
package.json
the fields inside.
For example, the following is one
package.json
.
{ "name": "foo", "version": "1.2.5", "scripts": { "view": "node view.js" } }
Then, the variable
npm_package_name
returns
foo
, the variable
npm_package_version
returns
1.2.5
.
// view.js console.log(process.env.npm_package_name); // foo console.log(process.env.npm_package_version); // 1.2.5
In the above code, we
process.env
get
package.json
the field value
through the environment variable
object
.
If it is a Bash script, you can use
$npm_package_name
and
$npm_package_version
get these two values.
npm_package_
The prefix also supports nested
package.json
fields.
"repository": { "type": "git", "url": "xxx" }, scripts: { "view": "echo $npm_package_repository_type" }
In the above code,
repository
the
type
attributes of the
field
can be
npm_package_repository_type
obtained through.
Here is another example.
"scripts": { "install": "foo.js" }
In the above code,
npm_package_scripts_install
the value of the variable is equal to
foo.js
.
Then, the npm script can also
npm_config_
get the npm configuration variables
through the
prefix, that is
npm config get xxx
, the value returned by the command.
For example, the release label of the current module can be
npm_config_tag
obtained through.
"view": "echo $npm_config_tag",
Note that
package.json
the
config
objects
inside
can be overridden by environment variables.
{ "name" : "foo", "config" : { "port" : "8080" }, "scripts" : { "start" : "node server.js" } }
In the above code, the
npm_package_config_port
variable returned is
8080
.
This value can be overridden by the following method.
$ npm config set foo:port 80
Finally, the
env
command can list all environment variables.
"env": "env"
10. Examples of commonly used scripts
// 删除目录 "clean": "rimraf dist/*", // 本地搭建一个 HTTP 服务 "serve": "http-server -p 9090 dist/", // 打开浏览器 "open:dev": "opener http://localhost:9090", // 实时刷新 "livereload": "live-reload --port 9091 dist/", // 构建 HTML 文件 "build:html": "jade index.jade > dist/index.html", // 只要 CSS 文件有变动,就重新执行构建 "watch:css": "watch 'npm run build:css' assets/styles/", // 只要 HTML 文件有变动,就重新执行构建 "watch:html": "watch 'npm run build:html' assets/html", // 部署到 Amazon S3 "deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/", // 构建 favicon "build:favicon": "node scripts/favicon.js",
11. Reference link
- How to Use npm as a Build Tool , by Keith Cirkel
- Awesome npm scripts , by Ryan Zimmerman
(over)