npm script

读书少了最近才看到这篇文章 Why we should stop using Grunt & Gulp。文章中笔者建议大家使用 npm 作为替代方案,绝对要打 call。npm 的 scripts 配置可以更简单的实现这些构建工具的所有功能。确实,npm script 相比 grunt、gulp 之类的构建工具简单很多,它消除了这些构建工具所带来的抽象层,并带给我们更大的自由度。而且随着社区的发展,各种基础工具你都可以信手拈来,只要你会使用 npmjs.com 去搜索,或者去 libraries.io 上搜索(当然我们公司的工作流还是在农耕火种时代。

npm script

npm 为我们提供了快速创建 package.json 文件的命令 npm init,执行该命令会问几个基本问题,如包名称、版本号、作者信息、入口文件、仓库地址、许可协议等,多数问题已经提供了默认值。

npm 允许在 package.json 文件里面,使用 scripts 字段定义脚本命令,而执行它的是 npm 核心命令之一的 npm run-script 命令(简称 npm run ),npm run 就会自动新建一个 Shell 并且可以从 package.json 中解析出 scripts 对象,然后将该对象的键作为 npm run 的第一个参数,它会在操作系统的默认终端中执行该键对应的命令。例如下面的 package.json:

1
2
3
4
5
6
7
8
9
10
{
'name': 'hello-npm-script',
'version': '0.1.0',
'main': 'index.js',
'scripts': {
'lint:js': 'eslint *.js',
'lint:css': 'stylelint *.less',
'test': 'npm run lint:js && npm run lint:css'
}
}

如果运行 npm run lint:js ,npm 将在终端中执行 eslint *.js。执行 npm run xxx 时会将 node_modules/.bin 加入终端的 PATH 环境变量中,这样你就可以直接运行那些作为依赖安装的二进制模块,也就是说你不需要 ./node_modules/.bin/eslint **.js$(npm bin)/eslint **.js 这样来指定命令的路径。

如果运行 npm run test 则表示子命令的执行顺序是先 lint:jslint:css 来,实现了多个 npm script 串行执行。

由于 npm 脚本就是 Shell 脚本,因为可以使用 Shell 通配符 也就是 *

钩子

npm 可以在 scripts 中为任何可执行的命令指定 pre-post- 钩子。例如,当运行 npm run lint:js 时,即便是没有在 scripts 中定义对应的 pre- 命令,npm 也会首先执行 npm run prelint:js,接着才是 npm run lint:js,最后是 npm run postlint:js

传递参数

-- 是 npm 用来传递参数的,例如 npm run lint:js -- a.js 将运行 eslint *.js a.js`

命令行自动补全

  • 不带任何参数运行 npm run 能列出 scripts 对象中定义的所有命令,,再结合管道操作符、less 命令( less 是 linux 里面的工具)

  • npm 自身也提供了自动完成工具 completion

跨平台运行

  • 使用 跨平台的命令

  • 使用 node packages 。可以使用 node packages 来取代 shell 命令。

痛点

因为 JSON 规范不支持添加注释,所以不能在 package.json 里添加注释。

常用脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 删除目录
"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",

参考链接