目录 · 9 个章节
egg-artisan: 提供一个基于egg的命令行运行模式。
前言
目前 egg 是没有基于开发业务功能的命令行运行模式的,比如我想在命令行执行个命令来处理一些业务相关的事,像数据库处理,缓存操作,文件操作等。当然egg-bin和egg-scripts也是命令行模式,但它们主要是项目维护,集成等作用,不是基于开发功能的。在 GitHub 找了好久没找到,于是就有个实现该想法的念头。
简介
egg-artisan 是基于 common-bin 的,为什么是 common-bin ?只能说命令行包这块自己也就对 common-bin 比较了解(如果有更好或更适合的欢迎提出),但功能上已经足够用了。egg-artisan在run()方法里注入了this.ctx,于是命令行也就有了操作 egg 项目内服务的能力,即能处理项目内业务相关的事。使用上,我们可以通过执行 npm run artisan xxx 来处理一些事。额外,也提供了app.runArtisan(command, argvs)方法使得能够在程序内也能调用。
过程中学习到了一些内容:
- common-bin, yargs 的学习
- egg 的启动流程
- egg-schedule, egg-mock 的学习
以下是具体README,尝试了把纯英文,有疑问或建议欢迎指出,谢谢!
Install
$ npm i egg-artisan --save
Mount
// {app_root}/config/plugin.js
exports.artisan = {
enable: true,
package: 'egg-artisan',
};
Features
egg-artisanprovides a cli running mode for egg. In the root directory, you can do something by executing commands likenpm run artisan xxx, such as operating file, manipulating database scripts, updating cache scripts, etc.
egg-artisan based on common-bin(based on yargs), to provide more convenient usage, as detailed below.
Usage
egg-artisan requires cli file to be stored in app/artisan, as shown below, test.js, clone.js.
egg-project
├── app
│ ├── artisan
│ | ├── test.js
│ | └── clone.js
│ ├── controller
| ├── router.js
| | ...
├── package.json
├── config
├── test
├── app.js (可选)
├── ...
How to write command
Let's take test.js as an example, for the file operation.
As you can see, the usage of the command is the same as that of common-bin, because egg-artisan extends common-bin. In addition, egg-artisan injected ths.ctx into the run method, so you can get anonymous context with ths.ctx.
You can see common-bin, http://yargs.js.org/docs for more detail.
// {app_root}/app/artisan/test.js
'use strict';
const Command = require('egg-artisan');
class TestCommand extends Command {
constructor(rawArgv) {
super(rawArgv);
this.yargs.usage('test command');
this.yargs.options({
a: {
type: 'string',
description: 'test argv: a description',
},
});
}
async run({ argv }) {
const aa = argv.a || '';
const bb = argv.b || '';
const cc = argv._.join(',');
await this.ctx.service.file.write(`argv: ${aa}${bb}${cc}`);
const con = await this.ctx.service.file.read();
console.log('argv', argv);
return con;
}
get description() {
return 'test description';
}
}
module.exports = TestCommand;
Add egg-artisan to package.json scripts:
{
"scripts": {
"artisan": "egg-artisan"
}
}
Run the test command
- Show help, the following image has 2 custom commands:
test.js,clone.js.
$ npm run artisan
// The following is the same
// npm run artisan -- -h
// npm run artisan -- help
Why use
--? you can see http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html.
- Show
test.jscommand help
$ npm run artisan -- test -h
// The following is the same
// npm run artisan -- test help
- Run
test.jscommand
$ npm run artisan -- test -x=1 --type=2 a b
// The following is the same
// npm run artisan -- test -x=1 --type 2 a b
// npm run artisan -- test -x 1 --type 2 a b
Call the artisan command inside the project
egg-artisan provides app.runArtisan(artisanCommand, [argvs]) for running some commands inside the project. app.runArtisan(artisanName, [argvs]) accepts two parameters:
- artisanCommand: Relative path or absolute path in the app/artisan directory, such as
test,{app_root}/app/artisan/test; You can also append parameters, such astest -x=1 --type=2,{app_root}/app/artisan/test -x=1 --type=2. - argvs: command argvs, will be parsed and appended to
artisanCommand. support object, array, such as[ 'a', 'b' ],{ '--a': 1, '--b': 2 },{ a: true, '--b': 2 }.
Example:
// {app_root}/app/controller/home.js
'use strict';
const BaseController = require('./base');
class HomeController extends BaseController {
async index() {
await this.app.runArtisan('test', { '-a': 1 })
}
module.exports = HomeController;
more usage, reference npm run artisan:
npm run artisan -- test
app.runArtisan('test')
npm run artisan -- test -a=1
app.runArtisan('test -a=1')
app.runArtisan('test', { '-a': 1 })
npm run artisan -- test a b
app.runArtisan('test a b')
app.runArtisan('test', [ 'a', 'b' ])
npm run artisan -- test -a=1 --bb=2
app.runArtisan('test -a=1 --bb=2')
app.runArtisan('test', { '-a': 1, '--bb': 2 })
npm run artisan -- test -a=1 --bb=2 cc
app.runArtisan('test -a=1 --bb=2 cc')
app.runArtisan('test -a=1', { '--bb': 2, cc: true })
app.runArtisan('test', { '-a': 1, '--bb': 2, cc: true })
advanced usage
-
Combined
egg-schedule// {app_root}/app/schedule/xxx.js const Subscription = require('egg').Subscription; class ClusterTask extends Subscription { static get schedule() { return { type: 'custom', }; } async subscribe(data) { await this.ctx.app.runArtisan('test', { '-a': 1 }); } }
结语
如有问题或有优化的点,欢迎pr, star。