Midway CLI
由于 CLI 底层能力都来源于社区现有的模块功能,为了减少过渡封装带来的维护成本和理解成本,CLI 中的各项功能都将逐步变为社区现有的模块,同时 CLI 库将停止继续迭代。
为此后续的变化为
- 开发将从
midway-bin dev
变为mwtsc
- 编译将从
midway-bin build
变为tsc
- 测试将从
midway-bin test
变为mocha
或者jest
- 覆盖率将从
midway-bin cov
变为jest --coverage
或者其他类似指令
@midwayjs/cli
是新版本的 Midway 体系工具链,和 Serverless,以及原应用的工具链进行了整合。
基础入口
@midwayjs/cli
提供了两个入口命令。 midway-bin
和 mw
命令。
当 @midwayjs/cli
安装到全局时,一般使用 mw
命令,比如 mw dev
。当安装到项目中,做 cli 工具时,我们一般使用 midway-bin
命令,但是请记住,这两个命令是相同的。
dev 命令
以当前目录启动本地开发命令。
$ mw dev
--baseDir 应用目录,一般为 package.json 所在文件夹,默认为 process.cwd()
--sourceDir ts代码目录,默认会自动分析
-p, --port dev侦听的端口,默认为 7001
--ts TS模式运行代码
--fast 极速模式
--framework 指定框架,默认会自动分析
-f, --entryFile 指定使用入口文件来启动 bootstrap.js
--watchFile 更多的文件或文件夹修改侦听
--notWatch 代码变化时不自动重启
标准启动
$ midway-bin dev --ts
修改启动端口
针对 HTTP 场景, -p
或者 --port
可以临时修改端口。
$ midway-bin dev --ts --port=7002
修改启动路径
指定应用根目录,一般为 package.json 所在文件夹,默认为 process.cwd()
$ midway-bin dev --ts --baseDir=./app
修改ts源码路径
指定ts代码目录,默认会自动分析
$ midway-bin dev --ts --sourceDir=./app/src
修改 tsconfig.json 的位置
通过设置 TS_NODE_PROJECT 环境变量来指定tsconfig.json的位置。
$ cross-env TS_NODE_PROJECT=./tsconfig.dev.json midway-bin dev -ts
更快的启动方式
默认的启动方式为 ts-node,在文件数量特别多的情况下会比较慢,可以切换为 swc 等新的编译方式。
// 使用 ts-node 的快速dev模式
$ midway-bin dev --ts --fast
// 使用 swc 的快速dev模式
$ midway-bin dev --ts --fast=swc
监听文件变化
--watchFile
用于指定更多的文件或文件夹修改侦听,默认侦听 sourceDir
目录中 .ts
、.yml
和 .json
结尾的文件(可通过 --watchExt 参数指定更多扩展名),以及 baseDir
目录中的 f.yml
文件
// 指定多个文件,使用英文逗号分隔
$ midway-bin dev --ts --watchFile=./a.txt,./b.txt
// 指定多个文件夹和文件,使用英文逗号分隔
$ midway-bin dev --ts --watchFile=./test,./b.txt
--watchExt
:指定更多的侦听文件扩展名,默认为.ts
、.yml
和.json
// 指定多个文件扩展名,使用英文逗号分隔
$ midway-bin dev --ts --watchExt=.js,.html
本地单步Debug调试
--debug
参数启动 debug 模式,可以通过 chrome devtools
进行单步代码调试:
您可以通过 chrome://inspect/
打开 nodejs devtools
进行断点调试:
您也可以直接通过 chrome 浏览器打开命令行中输出的 devtools
协议的链接,给对应代码添加断点后调试:
如果您使用 vscode
,那么您可以使用 vscode 的 js debug terminal,在其中执行 dev 命令(无需添加 --debug
参数)启动就可以打断点调试了。
test 命令
以当前目录启动测试,默认使用 jest 工具,可以使用 --mocha 参数指定使用 mocha。
$ midway-bin test --ts
-c, --cov 获取代码测试覆盖率
-f, --file 指定测试文件,例如 ./test/index.test.ts
--ts TS模式运行单测
--forceExit jest forceExit
--runInBand jest runInBand
-w, --watch watch模式
--mocha 使用 mocha 进行单测
使用 mocha 进行单测时,需要手动安装 mocha
和 @types/mocha
两个依赖到 devDependencies
中:npm i mocha @types/mocha -D
。
如果项目中使用了 TypeScript 的 path alias,请参考:测试
使用 mocha 替代 jest
有些同学对 mocha 情有独钟,希望使用 mocha 作为测试工具。
可以使用 mocha 模式进行测试。
$ midway-bin test --ts --mocha
使用 mocha 进行单测时,需要手动安装 mocha
和 @types/mocha
两个依赖到 devDependencies
中:npm i mocha @types/mocha -D
。
配置 alias paths
当你在 tsconfig.json
中配置了 paths 之后,并且模块包导入使用了 paths ,则会存在 mocha 做单元测试会导致路径无法被解析,无法使用通过导入 tsconfig-paths/register
解决
// src/configuration.ts
import 'tsconfig-paths/register';
// ...
需要添加 tsconfig-paths
并且在测试的时候引用进行处理
$ npm install --save-dev tsconfig-paths
$ midway-bin test --ts --mocha -r tsconfig-paths/register
注意,由于 mocha 没有自带断言工具,需要使用其他如 assert,chai 等工具进行断言。
cov 命令
以当前目录启动测试,并输出覆盖率信息,默认使用 jest 工具,可以使用 --mocha 参数指定使用 mocha。
$ midway-bin cov --ts
当使用 mocha 进行单测覆盖率时,您需要安装以下额外依赖。
$ npm i mocha @types/mocha nyc --save-dev
check 命令
自动分析代码中存在的问题,并给出修复建议。
$ midway-bin check
目前已提供 32
项问题的校验。
build 命令
使用 mwcc(tsc)进行 ts 代码编译,适用于标准项目,Serverless 项目请使用 package。
$ midway-bin build -c
-c, --clean 清理构建结果目录
--srcDir 源代码目录,默认 src
--outDir 构建输出目录,默认为 tsconfig 中的 outDir 或 dist
--tsConfig tsConfig json 字符串或文件位置
--buildCache 保留构建缓存
deploy 命令
适用于 Serverless 项目发布到 Aliyun FC、Tencent SCF、Aws Lambda 等运行时。
执行 deploy 命令会自动执行 package。
$ midway-bin deploy
-y, --yes 发布的确认都是yes
--resetConfig 重置发布配置,AK/AK/Region等
--serverlessDev 使用 Serverless Dev 进行aliyun fc函数发布,目前默认为 funcraft
...兼容package命令的所有参数
函数发布时域名配置
在 f.yml
中配置 custom.customDomain
为 auto
,则在发布时会配置一个临时的自动域名:
custom:
customDomain: auto
如果要取消自动的域名,将 customDomain
改为 false
:
custom:
customDomain: false
如果有自定义域名,在 customDomain
中配置即可:
custom:
customDomain:
domainName: test.example.com
如果自定义的域名,需要使用 https,那么在 云控制台 配置好 https 证书之后,需要将 customDomain 设置为 false,避免下次发布时重置成 http:
custom:
customDomain: false
每个路由都部署成了一个函数
可以使用高密度方案,合并成一个函数,f.yml 加如下配置
aggregation:
main:
functionsPattern:
- '*'
aliyun 发布 AK 错误问题
在第一次进行aliyun发布或使用 --resetConfig
参数的时候都可以重置 ak。
不过要注意的是每次 ak 都会默认创建一个新的 access
分组,在修改配置时会自动生成分组名,如果要覆盖之前的 AK 需要手动输入,如图:
发布时默认使用的分组为 default
,如果您在修改配置时如上图使用了 default-2
,那么需要在发布的时候通过 --access
参数指定使用 default-2
:
midway-bin deploy --access=default-2
package 命令
适用于 Serverless 项目构建
$ midway-bin package
--npm npm client,默认为自动识别添加registry
--sourceDir 源代码所在目录,默认会自动分析
--buildDir 构建结果目标目录
--sharedTargetDir 共享文件目标目录,默认为static,参考 --sharedDir 参数
--sharedDir 构建时会拷贝此目录到结果目录内的 $sharedTargetDir 目录
--skipZip 跳过zip打包
--skipBuild 跳过ts代码构建
--tsConfig tsConfig json 字符串或文件位置
--function 指定打包哪几个函数,多个使用英文 , 分隔
参数详解
--function
:指定打包哪几个函数,多个函数使用英文 , 分隔
// 打包
midway-bin package --function=a,b,c
// 发布
midway-bin deploy --function=a,b,c
函数构建打包时文件拷贝逻辑
默认拷贝的内容包含 后端代码文件夹
(一般为 src
、faas前后端一体化一般为 src/apis
)内的所有非 .ts
后缀的文件,以及 项目根目录
下的以 .js
、.json
、.yml
为扩展名的所有文件和 config
、app
文件夹内的所有文件。
如果要拷贝额外的文件,可以通过在 f.yml
文件中添加 package
字段 中的 include
来指定,可以配置文件名,也可以通过 fast-glob
语法↗ 匹配,使用示例如下:
# ...已省略其他属性的展示
package:
include: # 通过 include 属性指定额外打包文件配置
- static # 项目根目录下的 static 文件夹
- a.json # 项目根目录下的 a.json 文件
- a/b/c.js # 项目根目录下的 a 目录下的 b 目录下的 c.js 文件
- a/b/c.json # 项目根目录下的 a 目录下的 b 目录下的 c.js 文件
- xxx/**/*.js # 项目根目录下的 xxx 目录下的所有 js 文件
实验性功能
在 f.yml
中通过 experimentalFeatures
配置开启实验性功能
1. ignoreTsError
在构建时忽略ts error,不中断构建过程。
experimentalFeatures:
ignoreTsError: true
2. removeUselessFiles
在构建时移除大量无效文件,例如 LICENSE
、*.ts.map
、**/test/
等文件,可以有效减少构建包尺寸。
experimentalFeatures:
removeUselessFiles: true
3. fastInstallNodeModules
在构建时从当前的 devDependencies 中挑选出 production 依赖进行发布,可能会显著提升发布速度。
experimentalFeatures:
fastInstallNodeModules: true
CLI 扩展
1. 生命周期扩展
用户可以在 package.json
中添加 midway-integration
字段来根据各个命令的生命周期扩展 cli 的行为。
比如,在 package 命令 installDevDep
的后面添加自定义逻辑:
{
"midway-integration": {
"lifecycle": {
"after:package:installDevDep": "npm run build"
}
}
}
其中 lifecycle
的格式为 ${ 'before' | 'after' | '' }:${ 命令 }:${ 命令生命周期 }
。
package命令的声明周期列表:
'cleanup', // 清理构建目录
'installDevDep', // 安装开发期依赖
'copyFile', // 拷贝文件: package.include 和 shared content
'compile', //
'emit', // 编译函数 'package:after:tscompile'
'analysisCode', // 分析代码
'copyStaticFile', // 拷贝src中的静态文件到dist目录,例如 html 等
'checkAggregation', // 检测高密度部署
'generateSpec', // 生成对应平台的描述文件,例如 serverless.yml 等
'generateEntry', // 生成对应平台的入口文件
'installLayer', // 安装layer
'installDep', // 安装依赖
'package', // 函数打包
'finalize', // 完成
2. 通过插件进行扩展
用户可以自己编写 cli 插件,通过插件来实现更为复杂的 cli 的行为,也可以添加自定义命令。 目前支持两种插件:
- npm 插件,插件是一个npm包
- local 插件,插件在本地位置
通过在 f.yml 文件中配置 plugins
字段使 cli 加载插件:
plugins:
- npm::test-plugin-model
- local::./test/plugin
plugin 配置格式为: ${ 'npm' | 'local' }:${ provider || '' }:${ pluginName || path }
插件的代码参考:
// src/index.ts
import { BasePlugin } from '@midwayjs/command-core';
export class TestLalalaPlugin extends BasePlugin {
commands = {
lalala: {
usage: '自定义命令',
lifecycleEvents: [
'a', // 自定义生命周期
'b',
],
// 暂无
options: {
name: {
usage: '参数 name, 例如: mw lalala --name=123',
shortcut: 'n', // 参数缩写
},
},
},
};
hooks = {
// 添加当前插件内的命令生命周期扩展
// lalala 命令的 a 生命周期
'lalala:a': async () => {
// 输出
this.core.cli.log('lalala command hook');
// 获取用户输入的参数
this.core.cli.log(this.core.options);
// f.yml 内容
this.core.cli.log(this.core.service);
// 仅在 -V 参数下输出的内容
this.core.debug('lalala');
},
// 添加其他插件内的命令生命周期扩展
// 在 package 命令的 copyFile 生命周期 “之前” 执行
'before:package:copyFile': async () => {
console.log('package command hook');
},
};
}