为了提升研发体验,我们提供了便捷的方式在本地进行开发、调试、单元测试等。
在这里我们需要使用到 egg-bin 模块(只在本地开发和单元测试使用,如果线上请参考 aone部署)。
首先,我们需要把 egg-bin
模块作为 devDependencies
引入:
$ npm i egg-bin --save-dev
在 package.json
声明�框架
{
"...": "...",
"egg": {
"framework": "beidou-core"
}
}
本地启动应用进行开发活动,当我们修改代码并保存后,应用会自动重启实时生效。
添加 npm scripts
到 package.json
:
{
"scripts": {
"dev": "egg-bin dev"
}
}
这样我们就可以通过 npm run dev
命令启动应用。
本地启动的应用是以 env: local
启动的,读取的配置也是 config.default.js
和 config.local.js
合并的结果。
本地启动应用默认监听 7001 端口,可指定其他端口,例如:
{
"scripts": {
"dev": "egg-bin dev --port 7001"
}
}
这里主要讲解工具部分的使用,更多关于单元测试的内容请参考这里。
添加 npm scripts
到 package.json
:
{
"scripts": {
"test": "egg-bin test"
}
}
这样我们就可以通过 npm test
命令运行单元测试。
测试用例执行时,应用是以 env: unittest
启动的,读取的配置也是 config.default.js
和 config.unittest.js
合并的结果。
运行 npm test
时会自动执行 test 目录下的以 .test.js
结尾的文件(默认 glob 匹配规则 test/**/*.test.js
)。
我们在编写用例时往往想单独执行正在编写的用例,可以通过以下方式指定特定用例文件:
$ TESTS=test/x.test.js npm test
支持 glob 规则。
Mocha 支持多种形式的 reporter,默认使用 spec
reporter。
可以手动设置 TEST_REPORTER
环境变量来指定 reporter,例如使用 dot
:
$ TEST_REPORTER=dot npm test
默认执行超时时间为 30 秒。我们也可以手动指定超时时间(单位毫秒),例如设置为 5 秒:
$ TEST_TIMEOUT=5000 npm test
egg-bin test
除了环境变量方式,也支持直接传参,支持 mocha 的所有参数,参见:mocha usage 。
$ # npm 传递参数需额外加一个 `--`,参见 https://docs.npmjs.com/cli/run-script
$ npm test -- --help
$
$ # 等同于 `TESTS=test/**/test.js npm test`,受限于 bash,最好加上双引号
$ npm test "test/**/test.js"
$
$ # 等同于 `TEST_REPORTER=dot npm test`
$ npm test -- --reporter=dot
$
$ # 支持 mocha 的参数,如 grep / require 等
$ npm test -- -t 30000 --grep="should GET"
egg-bin 已经内置了 nyc 来支持单元测试自动生成代码覆盖率报告。
添加 npm scripts
到 package.json
:
{
"scripts": {
"cov": "egg-bin cov"
}
}
这样我们就可以通过 npm run cov
命令运行单元测试覆盖率。
$ egg-bin cov
test/controller/home.test.js
GET /
✓ should status 200 and get the body
POST /post
✓ should status 200 and get the request body
...
16 passing (1s)
=============================== Coverage summary ===============================
Statements : 100% ( 41/41 )
Branches : 87.5% ( 7/8 )
Functions : 100% ( 10/10 )
Lines : 100% ( 41/41 )
================================================================================
还可以通过 open coverage/lcov-report/index.html
打开完整的 HTML 覆盖率报告。
和 test
命令一样,cov
命令执行时,应用也是以 env: unittest
启动的,读取的配置也是 config.default.js
和 config.unittest.js
合并的结果。
对于某些不需要跑测试覆盖率的文件,可以通过 COV_EXCLUDES
环境变量指定:
$ COV_EXCLUDES=app/plugins/c* npm run cov
$ # 或者传参方式
$ npm run cov -- --x=app/plugins/c*
添加 npm scripts
到 package.json
:
{
"scripts": {
"debug": "egg-bin debug"
}
}
这样我们就可以通过 npm run debug
命令通过 V8 Inspector port
调试应用。
执行 debug
命令时,应用也是以 env: local
启动的,读取的配置是 config.default.js
和 config.local.js
合并的结果。
找到你需要设置断点的文件,设置一个断点,访问一下,就进入断点调试了。
在 Node.js 8.x 后,不再输出完整的调试地址,仅输出如下的日志:
> egg-bin dev "--inspect"
Debugger listening on ws://127.0.0.1:9229/fd7c6a26-5aa6-4c76-9310-045368fdaabc
...
2017-06-08 09:28:31,035 INFO 28121 [master] agent_worker#1:28131 start with clusterPort:54285
Debugger listening on ws://127.0.0.1:5856/7aa12781-6452-4160-829e-2ef037d39658
...
2017-06-08 09:28:31,366 INFO 28121 [master] app_worker#1:28132 start, state: none, current workers: ["1"]
Debugger listening on ws://127.0.0.1:9230/d1ad683d-a261-4f78-b9a2-77e8117a0aa0
分别对应于 master / agent / worker 的调试端口,我们一般关注最后一个即可,如上即 9230
。
- 访问 chrome://inspect 页面。
- 点击
Configure...
。 - 增加
localhost:9230
。 - 在
Remote Target
里面访问对应的链接即可(包含app_worker
的那个)。
框架内置了日志 功能,使用 logger.debug()
输出调试信息,推荐在应用代码中使用它。
// controller
this.logger.debug('current user: %j', this.user);
// service
this.ctx.logger.debug('debug info from service');
// app/init.js
app.logger.debug('app init');
通过 config.logger.level
来配置打印到文件的日志级别,通过 config.logger.consoleLevel
配置打印到终端的日志级别。
debug 模块是 Node.js 社区广泛使用的 debug 工具,很多模块都使用它模块打印调试信息,Egg 社区也广泛采用这一机制打印 debug 信息,推荐在框架和插件开发中使用它。
我们可以通过 DEBUG
环境变量选择开启指定的调试代码,方便观测执行过程。
(调试模块和日志模块不要混淆,而且日志模块也有很多功能,这里所说的日志都是调试信息。)
开启所有模块的日志:
$ DEBUG=* npm run dev
开启指定模块的日志:
$ DEBUG=egg* npm run dev
单元测试也可以用 DEBUG=* npm test
来查看测试用例运行的详细日志。
添加 npm scripts
到 package.json
:
{
"scripts": {
"debug": "egg-bin dev $NODE_DEBUG_OPTION"
}
}
目前 WebStorm 还不支持
--inspect
故不能使用egg-bin debug
,暂时使用egg-bin dev --debug
的方式。
使用 WebStorm 的 npm 调试启动即可:
使用 VSCode 进行调试
由于在开发阶段,当我们修改代码并保存后,应用会自动重启 worker。但是每次 worker 的更新都会使得调试端口发生变化,而 VSCode 是需要 attach 到固定的调试端口的。于是我们启用了一个叫 proxyworker
的代理服务,worker 的调试信息会被代理到这个服务上。这样 VSCode 通过固定 attach 到 proxyworker 来调试 worker 了。
下面是安装使用步骤:
1. 安装 egg-development-proxyworker 插件
npm i egg-development-proxyworker --save
// config/plugin.js
exports.proxyworker = {
enable: true,
package: 'egg-development-proxyworker',
};
// config/config.default.js
// 如果10086被占用,你可以通过这个配置指定其他的端口号
exports.proxyworker = {
port: 10086,
};
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Egg",
"type": "node",
"request": "launch",
"cwd": "${workspaceRoot}",
"runtimeExecutable": "npm",
"windows": {
"runtimeExecutable": "npm.cmd"
},
"runtimeArgs": [
"run", "dev", "--", "--debug"
],
"protocol": "legacy",
"port": 5858
},
{
"name": "Attach Agent",
"type": "node",
"request": "attach",
"port": 5856
},
{
"name": "Attach Worker",
"type": "node",
"request": "attach",
"restart": true,
"port": 10086
}
],
"compounds": [
{
"name": "Debug Egg",
"configurations": ["Launch Egg", "Attach Agent", "Attach Worker"]
}
]
}
由于 V8 Debugger Legacy Protocol 会在 Node.js 8.x 后被移除, 而替换使用的是 Inspector Protocol
新的协议主要有三大优势:
- 支持非常大的 JavaScript 对象
- 支持 ES6 Proxy
- 支持 Source Map 更好
当且仅当你的 Node.js 版本大于 7.x 时,可以使用 Inspector Protocol 进行调试。
VScode 升级 1.14 后,默认 protocol 由 [Legacy] 变为了 [Inspector]。如果仍需使用 [Legacy], 需手动指定。详情参考 microsoft/vscode#30629 (comment)
在上面的调试配置中需要修改一些参数来开启新协议:
Launch Egg
调整参数"runtimeArgs": ["run", "debug"]
、"protocol": "inspector"
Attach Worker
添加参数"protocol": "inspector"
此外,如果使用新协议还可以通过 chrome devtools 进行调试, 调试地址:
chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:10087
在 VSCode 中,切换到调试页面。选择 Debug Egg 配置进行启动。
更多 VSCode Debug 用法可以参见文档: Node.js Debugging in VS Code
如果想了解更多本地开发相关的内容,例如为你的团队定制一个本地开发工具,请参考 egg-bin。