前端学习笔记(十二)-npm scripts学习

2,027 阅读4分钟

今天学习 npm scripts。本想再学习 webpack 的,但是感觉应该来不及了。

学习材料是阮一峰的教程,还有官方文档用于参考。

1. npm scripts 介绍

npm scripts 写在 package.json 里的 "scripts" 属性里。

{
	...
	"scripts": {
		"test": "node test.js"
		...
	}
	...
}
    • 执行 npm run test 就相当于执行 node test.js
    • 可以用 npm run 查看所有脚本命令。
  1. yarn 也可以用 yarn run test 或者 yarn run

2. npm scripts 运行原理

每次执行 npm run 的时候,会新建一个 shell,然后在 shell 上执行脚本命令。只要是可以在 shell 上执行的命令,就可以写在 npm scripts 里,不一定非得是 node 命令,甚至可以脚本里运行脚本。
特别的是,node_modules/.bin 会被加入环境变量。

3. 通配符

其实就是使用 shell 通配符。

  • * 表示任意文件名,** 表示任意子目录名。

      "scripts": {
      	"testFile": "node *.js",
      	"testDir": "node **/*.js"
      }
    
  • *可用 \ 转义。 "testStar": "node my\*.js"

4. 添加参数

如果要往脚本里添加参数,需要先通过 -- 声明,如下:

npm run testScript -- --myArg1 
  1. 这里有两个 --,第一个 -- 表示要添加参数了,第二个 -- 和参数连在一起表示整个参数形式。
  2. 如果是 yarn,这里就不需要第一个 -- 来声明了。直接 yarn run testScript --myArg1 即可。
  3. 也可以在 package.json 里再封装个命令,如:
"scripts": {
	"test": "npm list -g",
	"test:ls": "npm list -g --depth=0",
	"test:ls2": "npm run test -- --depth=0" // 甚至可以套娃
}

冒号就只是冒号,没什么特殊含义,运行就打 npm run test:ls

5. 控制多个命令执行顺序

& 表示同时运行,&& 表示前一个运行成功后在运行下一个。

把上面的 "test:ls" 改成 "npm list -g --depth=0 && exit 1" 后运行下面的命令。

npm run test:ls & npm run test:ls2 // 第二个能运行
npm run test:ls && npm run test:ls2 // 第二个不运行

6. 默认脚本

npm 本身提供了两个可以直接运行的脚本。

npm run start
npm run install

// 两者的脚本分别为
"start": "node server.js"
"install": "node-gyp rebuild"

如果没有 server.js 这些文件,这些命令自然也没法用

7. hook

钩子函数是通过特殊命名来完成的,在命令名字前加上 prepost,如:

"scripts": {
	"pretest": "echo 1",
	"test": "echo 2",
	"posttest": "echo 3"
}

这样的话,即使只执行 npm run test,但实际上执行的是:

npm run pretest && npm run test && npm run posttest

所以尽量不要给别的脚本以 pre/post 开头命名,免得混淆。
当然还可以用套娃方式运行多个脚本。

  • 双重 pre 是无效的,如 prepretest

8. 简写

npm 提供了几种常用命令的简写。

npm start 为 npm run start 的简写
npm stop 为 npm run stop 的简写
npm test 为 npm run test 的简写
npm restart 为 npm run stop && npm run restart && npm run start 的简写

但是实际上 npm restart 的钩子执行顺序有点不一样,执行顺序为:

*npm run prerestart
 
npm run prestop
npm run stop
npm run poststop
 
*npm run restart
 
npm run prestart
npm run start
npm run poststart
 
*npm run postrestart

* 标明 restart 钩子运行的顺序,是分开的。

9. 变量

npm scripts 的一个特性是可以提供 npm 相关的变量。并且只能在使用 npm scripts 执行的时候才能使用。

9.1 变量的使用

假如我们有这两个文件:

// package.json
"scripts": {
    // 全都执行 view.js
    "preview": "node view.js",
    "view": "node view.js",
    "postview": "node view.js" 
}
// view.js
console.log(process.env.npm_lifecycle_event);
  1. npm_lifecycle_event 这个变量的值为目前正在执行的脚本名称,因此如果我们运行 npm run view,则会打印的内容见下:

     preview
     view
     postview
    
  2. 如果不用 js ,直接在 windows 里访问则是 %npm_lifecycle_event%

     // package.json
     "scripts": {
         "preview": "echo %npm_lifecycle_event%",
         "view": "echo %npm_lifecycle_event%",
         "postview": "echo %npm_lifecycle_event%" 
     }
    

    打印内容同 js 版本。

  3. 如果是直接在 bash 里访问则是 $npm_lifecycle_event

9.2 变量的种类

上面提到的是个特殊变量。
除此之外还有一些变量以类似方式命名,表示某种类似属性。

  1. 一些变量是以 npm_package_ 开头的变量,可以用来访问 package.json 里的各种字段。
    假设我们有:
// package.json
"name": "red-tea-and-good-weather",
"version""11.45.14",
"description": "best-match",
"dependencies": {
	"lodash": "^4.17.20"
}

则前三个可以通过 npm_package_namenpm_package_versionnpm_package_description 获取这些值。
即使最后一个也可以通过命名嵌套方式获得: npm_package_dependencies_lodash

  1. 还有一些变量以 npm_config_ 开头,获得的值为通过 npm get xxx 得到的值。如 npm_config_init_author_namenpm_config_init_license

  2. 如果想查看所有环境变量的名字,使用 npm run env,不过 yarn run env 的显示方式更加友好。