npm script 与 glob
2016-07-24 · 586 chars · 3 min read
好久好久好久没有写文章了,因为最近的闲暇时间全部贡献给了nfm
现在是广告时间,nfm 是一个基于 nodejs 的文件管理系统,目的是解决前端 cdn 静态资源的管理,前端使用 react+redux 实现,后端为 nodejs,目前还没完成(努力中),欢迎大家 star,https://github.com/keenwon/nfm。
在写 nfm 单元测试的时候,遇到个诡异的问题…
问题#
先看测试的目录结构
.
├── controllers
│ └── api
│ ├── deploy.spec.js
│ ├── fs.delete.spec.js
│ ├── fs.mkdir.spec.js
│ ├── fs.move.spec.js
│ ├── fs.rename.spec.js
│ ├── history.list.spec.js
│ ├── history.restore.spec.js
│ ├── list.spec.js
│ ├── undeploy.spec.js
│ └── upload.spec.js
├── eslint.spec.js
├── fetch.js
└── service
├── clean.backup.spec.js
└── clean.deploy.spec.js
以spec.js 结尾的全部是测试文件,那么显然,npm script 应 该这样写:
{
"script": {
"test": "_mocha test/**/*.spec.js"
}
}
但是悲剧的是,这样只执行了service 目录下的文件
为什么会这样#
那么为什么会这样呢?第一个想到的就是 mocha 的问题,检查之,在node_modules/.bin 下的_mocha 中输出process.argv,发现是已经解析好的两个文件。这个说,test/**/*.spec.js 传入前已经被解析好了。
那一定是 istanbul 的问题(用了 istanbul 检查覆盖率,具体见 nfm 源码),同样检查之,结果传入 Istanbul 的依然是解析好的文件。
难道是 npm 自己解析的?写个代码测一下:
. ├── node_modules │ └── .bin │ └── is └── package.json
其中,package.json 代码为:
{
"name": "npmscript",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "is /your-path/test/**/*.spec.js"
},
"author": "",
"license": "ISC"
}
除了 test 之外都是npm init 初始化的,is 的代码是:
#!/usr/bin/env node console.log(process.argv);
直接执行测试,果然,npm script 执行的时候会用 shell 本身的 glob 语法解析好。
解决#
那么现在的问题是,我用的是 zsh,可能有人用的是其他的。每种的 glob 语法貌似又不一样(为什么是貌 似,因为我还没来得及细查)。我们只能阻止 glob 语法在传入 mocha 前解析,而且传入 mocha 后,会使用 glob 模块解析,这样比较容易保证兼容性。所以,我们最初的代码这样改:
{
"script": {
"test": "_mocha \"test/**/*.spec.js\""
}
}
ok,解决,见两个引号当字符串传入。完。


