monorepo工程开发交互nodejs命令行程序

前言

[MixedCli](https://zhangfisher.github.io/mixed-cli/)monorepo应用开发命令行程序提供了一套解决方案,提供了更加友好的命令行开发体验。

第1步:创建工程

以一个典型的monorepo为例开始:


flexapp
  packages
     cli     
     core
     vue
     react

示例工程名为flexapp,工程中的包名分别是@flexapp/core@flexapp/cli@flexapp/vue@flexapp/react

第2步:创建命令行应用

@flexapp/cli是命令行应用,对外提供flexapp的命令行工具。

1. 安装依赖

::: code-group

npm install mixed-cli
pnpm add mixed-cli
yarn add mixed-cli

:::

2. 创建cli.js

@flexapp/cli包中创建cli.js文件,内容如下:

flexapp
  pacakges
    cli
      cli.js
      init.js
      package.json

主要内容如下:

::: code-group

const { outputStr,MixedCli } = require("mixed-cli") 
const initCommand = require("./init")

const cli = new MixedCli({
    name: "flexapp",
    version: "1.0.0",
    include: /^\@flexapp\//, 
    // 显示logo
    logo: String.raw`
        ____   ____                  __            
        \   \ /   /___   ___________|  | _______   
         \   Y   /  _ \_/ __ \_  __ \  |/ /\__  \  
          \     (  <_> )  ___/|  | \/    <  / __ \_
           \___/ \____/ \___  >__|  |__|_ \(____  /
                            \/           \/     \/`, 
})
cli.register(initCommand)
cli.run()

{
  "name": "@flexapp/cli",
  "version": "1.0.0",
  "bin": {
    "flexapp": "cli.js"
  }
}

:::

@flexapp/cli仅仅是一个命令行的入口:

  • 重点:include: /^\@flexapp\// 的意思是告诉mixed-cli,当执行flexapp命令时,会在当前工程中搜索以@flexapp/开头的包,然后包中声明在cli文件夹下的所有命令被合并到flexapp命令中。
  • @flexapp/cli中使用cli.register(iniCommand),注册一个通用的init命令,该命令的实现在init.js中。 一般可以在此工程提供一些通用命令,而其他的命令声明逻辑在分别在@flexapp/*/cli/*.js等包中实现。

第3步: 创建命令

从上面可以看到@flexapp/cli非常简单,主要是一些通用的命令和命令行的入口。而真正的命令声明在其他的包中,比如@flexapp/vue@flexapp/react等包中。

然后接下来,我们在@flexapp/vue中创建一个dev命令,用于启用vue项目。

flexapp
  pacakges
    cli
        cli.js
        dev.js
        package.json
    vue
        src
            index.ts
            cli
                dev.js      // dev命令的实现
        pacakge.json

接下来我们编写dev.js文件,内容如下:

::: code-group


const { MixedCommand } = require('mixed-cli');

/**
 * @param {import('mixed-cli').MixedCli} cli
 */
module.exports = (cli)=>{                

    const devCommand = new MixedCommand();
    devCommand
        .name('dev')
        .description("以开发模式启动应用")      // 未指定默认值,自动使用text类型提供                       
        .option("-p,--port ","指定端口号",3000)                      
        .option("-d,--debug" ,"调试模式",{ default:true,prompt:true })      
        .option("-h,--host ","指定主机名",{default:"localhost",prompt:true})                         
        .option("-e,--env [value]","环境变量",{ prompt:false })                                   
        .option("-m,--mode ","指定模式",{choices:["development","production","test","debug"]})
        .option("-f,--framework [value]","开发框架",{choices:[
            {title:"vue",value:1},
            {title:"react",value:2,description:"默认"},
            {title:"angular",value:3}
        ]})
        .option("-o,--open","自动打开浏览器",{prompt:{          // 自定义提示
            type:"toggle",
            message:"是否自动打开浏览器?",
        }})
        .action((options)=>{            
            console.log("run dev")
        })

    return devCommand
} 
    
   

{
  "name": "@flexapp/vue",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "mixed-cli": "^1.0.0"
  }
}

:::

  • src/cli目录下创建dev.js文件,用于声明dev命令。cli目录下的所有js文件会被自动加载,每个文件均导出一个函数,该函数需要返回一个或多个MixedCommand实例。cli目录是一个默认的约定目录,可以通过cli.cliDir参数修改。
  • 创建MixedCommand实例,用于声明命令。MixedCommand继承自commanderCommand类,因此可以使用commander的所有特性。
  • package.json只需要将mixed-cli添加为依赖即可。
  • 同样地,我们可以在@flexapp/react,@flexapp/app等包中创建其他的命令。

第4步: 使用命令

我们在flexapp应用中开发。

  • 安装@flexapp/cli

::: code-group

npm install @flexapp/cli @flexapp/vue
pnpm add @flexapp/cli @flexapp/vue
yarn add @flexapp/cli @flexapp/vue

:::

安装@flexapp/cli包后,就可以在命令行中使用flexappflexapp init命令了。

此时执行一下flexapp命令,会看到如下输出:

____   ____                  __
\   \ /   /___   ___________|  | _______
 \   Y   /  _ \_/ __ \_  __ \  |/ /\__  \
  \     (  <_> )  ___/|  | \/    <  / __ \_
   \___/ \____/ \___  >__|  |__|_ \(____  /
                    \/           \/     \/
版本号:1.0.0 
Usage: flexapp [options] [command]

Options:
  -v, --version      当前版本号
  -h, --help         显示帮助

Commands:
  init [options]    初始化应用  // 只有这个命令 
  • 接下来我们安装@flexapp/vue

::: code-group

npm install @flexapp/vue @flexapp/vue
pnpm add @flexapp/vue @flexapp/vue
yarn add @flexapp/vue @flexapp/vue

:::

此时再执行一下flexapp命令,会看到如下输出:

____   ____                  __
\   \ /   /___   ___________|  | _______
 \   Y   /  _ \_/ __ \_  __ \  |/ /\__  \
  \     (  <_> )  ___/|  | \/    <  / __ \_
   \___/ \____/ \___  >__|  |__|_ \(____  /
                    \/           \/     \/
版本号:1.0.0 
Usage: flexapp [options] [command]

Options:
  -v, --version      当前版本号
  -h, --help         显示帮助

Commands:
  init [options]    初始化应用  
  # dev命令是由@flexapp/vue包提供的
  dev [options]     以开发模式启动应用  //   [!code ++]

第5步: 自动推断交互提示

在上面dev命令中,共指定了6个选项,当执行flexapp dev命令时, 会根据配置自动交互引导用户输入选项,如下:

  • 命令行的交互体验与使用commander时完全一样
  • 仅当选项未指定默认值或满足一定条件时,才会根据一定的规则自动推断交互提示类型。详见自动推断交互提示
  • MixedCli使用prompts来实现交互提示,因此支持prompts的所有交互类型特性。详见prompts

小结

  • MixedCli是一个基于commander的命令行工具开发框架,提供了一套命令行开发的最佳实践。
  • MixedCli能对所有命令行选项自动推断交互提示类型,当用户没有输入选项时,会自动引导用户输入选项,提供友好的用户体验。
  • MixedCli可以在当前工程自动搜索满足条件的包下声明的命令进行合并,从而实现扩展命令的目的。此特性可以保持@flexapp/cli包的精简和稳定,给用户一致的体验。

你可能感兴趣的:(交互,node.js,前端,命令行,monorepo)