精华内容
下载资源
问答
  • 如何用node开发自己cli工具 灵感 写这个工具的灵感以及场景源于youtube的一次闲聊 github 地址 blog首发 使用场景 原本我们写博客展示shell,例如:安装运转docker,一键部署脚本,等一些终端操作,我们需要进行...
        

    如何用node开发自己的cli工具

    灵感

    写这个工具的灵感以及场景源于youtube的一次闲聊

    使用场景

    原本我们写博客展示shell,例如:安装运转docker,一键部署脚本,等一些终端操作,我们需要进行大量的截图展示给用户,为什么不能更加直观方便的生成一个网页呢?

    如何使用

    • 安装
      sudo npm install share_shell -g
    • 帮助
      tw --help   #1.0暂时用这个命令,没想到好的缩写

    tw --help

    • 查看版本
    tw --version || tw -v
    • 使用
     # tw share "要展示的命令" -p "路径"
     # 例如想 docker ps -a 秀一波你的docker容器
     tw share "docker ps -a" 或 tw s "docker ps -a"  # 默认生成 share_you_shell.html 到当前目录  
     
     # 还可以指定路径
     
     tw share "ls -all" -p /usr/local/html/share_shell.html  #自动创建文件,存在默认覆盖
    

    如何基于node制作自己的跨平台工具

    ① 制作前的思考

    • 涉及的技术栈,以及技术选型
    • shelljs 进行CMD处理

      首先我需要拿到windowslinux 的系统回调,使用 linux 中的 sed -n 'p;n;p' 获取输入任何命令的返回值在终端、那么首先考虑shelljs API 单发现 对于 sed 处理的很少,并不能满足我们的需求,但是看到了一个万能函数 shell.exec ,我们用他的回调来接受我们的文本

    • fs 或 fs-extra

      fs-extra 对于 fs 的关系呢 就像是 lodashunderscore 前者封装了后者,并提供了更好的支持,并做到了向下兼容API 很不容易,我们主要用它生成一个简单的html文件来分享我们的shell

    • commander

      我们选用 commander 来制作 类似 git docker 风格的 cli 命令行工具 , 因为没有其他更好的选择

    • 其他

      我个人用了lodash string 进行了偷懒操作,缺点是增加了两个依赖,有点是快~

    ② 写代码前的准备工作

    • 初始化

      npm init 初始化生成标准的 package.json 文件,包含你的git信息,发布npm能找到你的描述,联系方式,版本号等。

    • 新建bin文件夹

      这是一个规范,可执行工具的老家。新建一个tw.js ,因为是打印机风格的,所以瞎起了个名字 取typeWriter首字母

    ③ 先定义一下基本的终端命令

    • 编辑 tw.js

      var program = require('commander');
      
      var appInfo = require('../package.json');
      
      program.version(appInfo.version) // 拿到 package.json 你定义的版本
      program
          .command('share <shell>') // 定义你的command
      
          .alias('s') // 缩写
      
          .description('Enter the "shell" you want to convert and include it in \" \"  ') // 描述
      
          .option("-p, --path <path>", "Enter you html path , default ./share_you_shell.html") // option 字命令,可以无限多个
      
          .action(function (cmd, options) {
          // 拿到cli输入的option子命令,没有可以默认
              var path = typeof options.path == 'string' ? options.path : "./share_you_shell.html"
              // 执行你的操作 ↓
              // 执行cli的command
              exec_shell.exec(cmd, (res) => {
                  // 回调的res根据格式转为数组
                  var res_arr = S(res).lines()
                  // 针对数组你的逻辑处理一波数组
                  let str = format.toTypedFormat([cmd].concat(res_arr))
                  // 异步制作你的文件,传入路径
                  file.mkfile(str, path)
              })
          }).on('--help', function () {
      
               // --help  commander 有默认处理,一般这部分无事可做,你还想干啥?
          });
      
      program.parse(process.argv);
      

    输入 tw -- help 大概是这样的

    tw --help

    • 完善代码

      完善一下你各单位的逻辑,当然你也可以选择写的更加优雅。

    • 预先注意的问题

      我这个项目我会预先想到:保留shell的转译符 使用pre 原型输入 \n \t,处理一下scroll 保持底部,最后随便找一个类似typewriterjs 开源库,按照他的风格生成一下就可以

    ④ 测试一下

    • 写完了?

      node /bin/tw.js share "tree -L 2" -p xxx 测试一下,(你们可能没有安装tree,换任何可执行的其他命令,长ping 除外)

    • 全局测一下

      我们最终是要发布到npm上的,可以让用户-g安装,自己应该先测试一下,

      首先:确保你在 package.json 文件中添加了 bin 节点。并指明了主程序,像我这样。

          "bin": {
              "tw": "./bin/tw.js"
            },
    • 运行

      sudo npm install . -g

    • 执行

      tw share "tree -L 2" -p xxx/xxx/xx.html

      如果生成了`xx.html`,恭喜你,可以发布了
      

      ④如何发布到npm进行装逼

    • 项目已经准备好了,接下来可以着手发布了。首先npm上注册账号,别忘了去邮箱验证。然后输入:

      npm adduser

      接下来会以问答的形式向你了解你的用户名、密码以及公开的邮箱,之后输入

      npm publish
    • 注意!!
      发布npm 的源别是 cnpm 淘宝源,否则 401

      然后看到进度条走,之后组件发布成功,可以到npm上搜索自己的包了。

      npm install share_shell (取决于你package.json当时填写的项目名)
      甚至你 cnpm install share_shell 也能下载,淘宝同步真他妈快。

    • npm i share_shell -g 全世界 所有 用户都可以下载了

    ⑤ 引发的思考

    • 思考

    node既然为我们提供了如此简洁的方式,那么我们可以做一些更有意义的事情,比如 为我们的开源项目 做一个 部署发布打包测试CLI工具集,可以做一些日常工作的批处理 ,比如以前工作中的场景:多台服务器 负载均衡 查看后端日志是个麻烦事,需要开很多终端,我们可不可以配置好rsassh 合并多个 管道 重定向为一个终端进行查看呢?

    feature(flag)

    • 做一个推荐

    1.0不够好,也就能个人blog站点用用,分享给别人瞧瞧,我打算下一步2.0发表到我即将完成的 目前技术栈比较主流的 bbs new-bee 上, 顺便推广一波,当然顺便点个 star支持一下也很感激,当然这也是我首次提及此项目,此项目涉及到docker webpack vue spring-boot shell脚本 各种中间件 各种前沿ui库脚手架 未来甚至可能尝试基于docker的微服务小型实践,总之想做的事情真的很多。

    关于我

    庄文达:全栈开发攻城狮

    • 就是爱学习,我还要刺激大家一起学习?
    • 没事喜欢造造轮子?
    • 写写博客?
    • 录录视频分享?
    • 做一些技术实践?
    • 立一立flag,不过都会还回来的?
    • 目前在写 bbs?

    下一篇文章

    • 我会给大家讲述一下全栈工程师的自我修养或者大方向可以说web全栈工程师的自我修养 和需要掌握的技术栈 ,也是分享我这么多年的积累

    最后展示一下新玩具吧

    下期见

    展开全文
  • 随着Create React App,Angular CLI和Ionic CLI等项目的普及以及这些cli带来的生产力,开发人员应该有一种简单的方法来使用样板创建自己CLI,并且向他们介绍CLI创建的世界。 该项目将使开发人员能够轻松快速地...
  • 4.切换到自己cli工具根目录下执行指令(我这里用的是yarn) (1)登录npm,用户名、密码、邮箱就是填写注册的npn对应的信息 yarn login (2)如果已经登录却不是想上传的账号则退出 yarn logout (3)上传cli ...

    前期准备:
    1.注册在github注册自己的账户
    2.在npm注册自己的账户并在设置中关联github
    在这里插入图片描述
    4.切换到自己的cli工具根目录下执行指令(我这里用的是yarn)
    (1)登录npm,用户名、密码、邮箱就是填写注册的npn对应的信息

    yarn login
    

    (2)如果已经登录却不是想上传的账号则退出

    yarn logout
    

    (3)上传cli

    yarn publish
    

    (4)如果本地是淘宝镜像源则换成

     yarn publish --registry=https://registry.yarnpkg.com
    
    展开全文
  • 年前在工作中接到任务要开发一个自己CLI,便去了解了一下。发现并不难,只需运用nodejs的相关api即可。 目前实现的功能为: 输入 new 命令从github下载一个脚手架模版,然后创建对应的app。 输入 create 命令可以...

    大家新年好!
    年前在工作中接到任务要开发一个自己的CLI,便去了解了一下。发现并不难,只需运用nodejs的相关api即可。

    目前实现的功能为:

    1. 输入 new 命令从github下载一个脚手架模版,然后创建对应的app。
    2. 输入 create 命令可以快速的创建一些样板文件。

    下面将分步去解析一个CLI的制作过程,也算是一次记录回忆的过程。

    1.创建CLI项目

    用 npm init 生成项目的package.json文件。然后编辑该文件主要加上

    "bin": {
        "jsm": "./bin/jsm.js"
      },
    复制代码

    然后在当前目录创建你自己的脚本文件,对应上述配置为 mkdir bin && touch bin/jsm.js
    编辑创建好的文件,加上

    #!/usr/bin/env node
    console.log('Hello CLI')
    复制代码

    接下来在项目的根目录运行一下 npm i -g, 现在就可以在命令行使用jsm命令了。
    注意: 一定要在开头加上#!/usr/bin/env node, 否则无法运行。

    详解:package.json文件只有加上了bin字段,才能在控制台使用你的命令,对应的这里的命令就是jsm,对应的执行文件为bin/jsm.js。 其实"jsm"命令就是 "node bin/jsm.js" 的别称,只有你用npm i -g全局安装后才可以用,开发的过程中直接用node bin/jsm.js即可。

    2.解析命令参数

    一个CLI需要通过命令行输入各种参数,可以直接用nodejs的process相关api进行解析,但是更推荐使用commander这个npm包可以大大简化解析的过程。 npm i commander安装, 然后更改之前的脚本文件添加

    const program = require('commander');
    
     program
      .command('create <type> [name] [otherParams...]')
      .alias('c')
      .description('Generates new code')
      .action(function (type, name, otherParams) {
        console.log('type', type);
        console.log('name', name);
        console.log('other', otherParams);
        // 在这里执行具体的操作
      });
    
    program.parse(process.argv);
    复制代码

    现在在终端执行一下 node bin/jsm.js c component myComponent state=1 title=HelloCLI 应该就能看到输入的各种信息信息了。至此命令解析部分就基本ok了,其他更多的用法可以参考官方例子

    详解:command第一个参数为命令名称,alias为命令的别称, 其中<>包裹的为必选参数 []为选填参数 带有...的参数为剩余参数的集合。

    3.下载模版创建文件

    接下来需要根据上一步输入的命令去做一些事情。具体到一个脚手架CLI一般主要做两件事,快速的生成一个新项目和快速的创建对应的样板文件。 既然需要创建文件就少不了对nodejs的fs模块的运用,这里用的一个增强版的fs-extra

    下面封装两个常用的文件处理函数

    //写入文件
    function write(path, str) {
      fs.writeFileSync(path, str);
    }
    //拷贝文件
    function copyTemplate(from, to) {
      from = path.join(__dirname, from);
      write(to, fs.readFileSync(from, 'utf-8'));
    }
    复制代码

    3.1 生成一个新项目

    命令如下

    program
      .command('new [name]')
      .alias('n')
      .description('Creates a new project')
      .action(function (name) {
        const projectName = name || 'myApp';
        init({ app: projectName })
      });
    复制代码

    init函数主要做了两件事:

    • 从github下载一个脚手架模版。(如用本地的脚手架模版可省略此步骤)
    • 拷贝脚手架文件到命令指定的目录并安装相应的依赖包。
    const fs = require('fs-extra');
    const chalk = require('chalk');
    const {basename, join} = require('path');
    const readline = require('readline');
    const download = require('download-git-repo');
    const ora = require('ora');
    const vfs = require('vinyl-fs');
    const map = require('map-stream');
    const template = 'stmu1320/Jsm-boilerplate';
    
    // 创建函数
    function createProject(dest) {
      const spinner = ora('downloading template')
      spinner.start()
      if (fs.existsSync(boilerplatePath)) fs.emptyDirSync(boilerplatePath)
      download(template, 'boilerplate', function (err) {
        spinner.stop()
        if (err) {
          console.log(err)
          process.exit()
        }
    
        fs
        .ensureDir(dest)
        .then(() => {
          vfs
            .src(['**/*', '!node_modules/**/*'], {
              cwd: boilerplatePath,
              cwdbase: true,
              dot: true,
            })
            .pipe(map(copyLog))
            .pipe(vfs.dest(dest))
            .on('end', function() {
              const app = basename(dest);
              const configPath = `${dest}/config.json`;
              const configFile = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
              configFile.dist = `../build/${app}`;
              configFile.title = app;
              configFile.description = `${app}-project`;
              write(configPath, JSON.stringify(configFile, null, 2));
              // 这一部分执行依赖包安装,具体代码请查看文末链接
              message.info('run install packages');
              require('./install')({
                success: initComplete.bind(null, app),
                cwd: dest,
              });
            })
            .resume();
        })
        .catch(err => {
          console.log(err);
          process.exit();
        });
    })
    }
    
    function init({app}) {
      const dest = process.cwd();
      const appDir = join(dest, `./${app}`);
      createProject(appDir);
    }
    复制代码

    3.2 快速生成样板文件

    生成样板文件这一部分,其实就是拷贝一个文件到指定的地方而已,当然还应该根据参数改变文件的具体内容。

    program
      .command('create <type> [name] [otherParams...]')
      .alias('c')
      .description('Generates new code')
      .action(function (type, name, otherParams) {
        const acceptList = ['component', 'route']
        if (!acceptList.find(item => item === type)) {
          message.light('create type must one of [component | route]')
          process.exit()
        }
        const params = paramsToObj(otherParams)
        params.name = name || 'example'
        generate({
          type,
          params
        })
      });
    
    //生成文件入口函数
    function generate({type, params}) {
      const pkgPath = findPkgPath(process.cwd())
      if (!pkgPath) {
        message.error('No \'package.json\' file was found for the project.')
        process.exit()
      }
      const dist = path.join(pkgPath, `./src/${type}s`);
      fs
        .ensureDir(dist)
        .then(() => {
          switch (type) {
            case 'component':
              // 具体代码请查看文末链接
              createComponent(dist, params);
              break;
    
            case 'route':
              createRoute(dist, params);
              break;
    
            default:
              break;
          }
        })
        .catch(err => {
          console.log(err);
          process.exit(1);
        });
    }
    复制代码

    到这里一个基本的脚手架CLI就差不多了,剩下的是帮助信息等友好提示的东西了。文章的所有源码点击这里
    也欢迎大家安装试用一下 npm i -g jsm-cli

    展开全文
  • 本文以自己的my-cli为例,将开发到发布过程完整记录下来,看完本文,你将学会如何从零开发一个cli项目,如何上传到github库,以及如何使用npm发布自己的包。 准备 开发一个cli工具前首先要想好它能做什么。以我自己...
  • 前端开发中,经常会用到一些CLI工具,ts-node转换ts文件,babel-cli来解析ES6+语法,还有初始化SPA项目的脚手架,create-react-app、vue-cli、vite等等,这些cli工具通过自动化脚本节约了开发者在配置webpack,...

    46d6789855b20f772d462a914a29e961.gif

    前端开发中,经常会用到一些 CLI 工具, ts-node 转换ts文件, babel-cli 来解析ES6+语法,还有初始化SPA项目的脚手架, create-react-app 、 vue-cli 、 vite 等等,这些cli工具通过自动化脚本节约了开发者在配置 webpack , tsconfig , babel 上面的时间,实现了快捷开发。但是你真的了解cli工具吗,下面就通过打造一个自定义的cli工具来讲讲其中的原理。

    CLI使用小窍门

    会写 react 的朋友肯定有用过 create-react-app ,脚手架的常见使用步骤会分成两步,第一步是全局安装,第二步执行cli,比如下面命令:

    # npm安装:
    npm install -g create-react-app
    # 或者yarn安装:
    yarn global add create-react-app
    # 执行cli:
    create-react-app my-project
    复制代码

    70654ddc8d038ae1274eb431ac0aa195.png

    但是如果想避免模块全局安装,可以尝试 npx , npx会先检查本地依赖包有没有可执行文件,如果找不到就会去远程仓库下载,并且会下载到临时文件,在使用完就删除,是不是有种阅后即焚的赶脚,比如:

    # npx安装:
    npx create-react-app my-project
    复制代码

    从npm的 6.1 版本开始,使用 npm init 或者 yarn create 命令可以直接省略 create- 前缀,比如 create-react-app 就变成如下:

    # npm安装:
    npm init react-app my-project
    # yarn安装:
    yarn create react-app my-project
    复制代码

    新的CLI项目

    CLI项目起名并不一定要 create-* 前缀,比如vue-cli,但是 create-xxx 确实让人更好理解,一般脚手架项目推荐用create,所以这里用来演示的demo就取名为 create-tst 。

    mkdir create-tst && cd create-tst
    npm init --yes
    复制代码

    --yes 跳过提示,创建默认配置的package.json

    接下来再创建一个接收命令,并执行脚本的js文件,常规做法是建一个 bin 目录放对应的js脚本文件,并在 package.json 中配置 "bin" 字段信息。

    mkdir bin && cd bin
    touch create-tst.js
    复制代码

    288b19b3ea667924eae84ed340477f1f.png

    create-tst.js的内容如下:

    #!/usr/bin/env node

    require = require('esm')(module /*, options*/);
    require('../src/cli').cli(process.argv);
    复制代码

    首先是使用本地的node命令,然后 esm 库是为了后面的执行代码能够支持ES6+语法,具体的cli逻辑一般会放在 src/cli.js 里执行, process.argv 是之后命令行执行的所有参数。

    在讲cli.js的逻辑之前,这里先列一下整体的目录结构:

    |____bin
    | |____create-app.js 命令行入口
    |____package.json
    |____templates
    | |____TypeScript js模板
    | |____JavaScript ts模板
    |____src
    |____main.js 执行create任务
    |____cli.js 处理用户输入
    复制代码

    还有相关的依赖(下文会提到每个依赖的用处):

    依赖库作用npm地址
    arg解析原始的命令行参数,返回对象传送门
    chalk让命令行输出支持高亮加粗传送门
    esm让node6+都支持ES6语法传送门
    execa执行其他的命令行语句传送门
    inquirer支持复杂的交互提示,比如选择,确认传送门
    listr管理执行任务,支持串行、并行传送门
    ncp异步执行文件复制传送门
    pkg-install在js中安装npm依赖包传送门

    交互式的UI

    执行脚本前,需要先在当前目录下执行一次 npm link 命令,这个命令会在全局环境下生成一个符号链接文件,文件的名字是package.json中制定的模块名,本地就可以执行 create-tst 命令

    解析入参

    在src目录下建一个cli.js文件,可以把命令行执行输入的参数打印出来看看:

    export async function cli(args) {
    console.log(args)
    }
    复制代码

    1b4d40fdbf4fbd4c54247b5c15a94869.png

    cli.js输出了一个数组,有五个元素,第一个和第二个都是固定的,后面三个都是用户自定义输入的参数,所以我们只用解析除了前两个外的所有参数,这时候就可以用arg来解析了。

    // 解析输入参数
    const parseArgsIntoOptions = (rawArgs) => {
    const args = arg({
    '--git': Boolean, // 解析成布尔值
    '--yes': Boolean,
    '--install': Boolean,
    '-g': '--git', // 参数映射,-g 等同于 --git
    '-y': '--yes',
    '-i': '--install',
    }, {
    argv: rawArgs.slice(2)
    })
    return {
    skipPrompts: args['--yes'] || false,
    initGit: args['--git'] || false,
    template: args._[0],
    runInstall: args['--install'] || false
    }
    }
    复制代码

    当然,用 commander 工具来解析也是一个不错的选择。

    如果arg第一个对象参数里没有配置,就会统一进入args._数组内,比如javascript

    GUI选择配置

    使用过vue-cli的朋友肯定知道创建项目的时候界面会提供vue不同的版本,或者自定义配置,这复杂的交互就需要用到上面说到的inquirer。 57233201ecd26b1fd30053ddc1cc2a7d.png

    这里我们就把通过提示获取相关配置的逻辑写成一个通用函数,如果用户不使用默认配置或没输入相关参数,就会出现提示:

    • 选择项目模板

    • 选择是否初始化git

    • 选择是否安装npm依赖

    const promptForOptions = async (options) => {
    const defaultTemplate = 'JavaScript';
    if (options.skipPrompts) {
    return {
    ...options,
    template: options.template || defaultTemplate
    }
    }

    const questions = [];
    if (!options.template) {
    // 1. 选择项目模板
    questions.push({
    type: 'list',
    name: 'template',
    message: '请选择当前新建项目的模板',
    choices: ['JavaScript', 'TypeScript'],
    default: defaultTemplate
    })
    }

    if (!options.initGit) {
    // 2. 选择是否初始化git
    questions.push({
    type: 'confirm',
    name: 'git',
    message: '是否初始化git仓库',
    default: false
    })
    }

    if (!options.runInstall) {
    // 3. 选择是否安装npm依赖
    questions.push({
    type: 'confirm',
    name: 'install',
    message: '是否安装依赖',
    default: false
    })
    }

    const answers = await inquirer.prompt(questions)

    return {
    ...options,
    template: options.template || answers.template,
    git: options.initGit || answers.git,
    install: options.runInstall || answers.install
    }
    }
    复制代码

    167aabb3427ca23a14a7523ee2e0d423.png b8552dce25969bf92184bac9c054c5f3.png 9c56657111c839f141b43e12e0aab799.png 效果不错,和 vue-cli 差不多

    最后改下一下cli函数,引入一个 createSpaApp ,具体的逻辑下面会提到。

    import createSpaApp from './main'

    function cli(args) {
    let options = parseArgsIntoOptions(args)
    options = await promptForOptions(options)
    createSpaApp(options)
    }
    复制代码

    核心功能

    有了配置后就可以考虑如何让配置的参数生效了,假设用户把所有配置都打开,那么就要做三件事情:

    1. 新建模板文件

    2. 初始化git仓库

    3. 安装npm依赖

    新建模板文件

    新建模板文件其实就是直接复制预设的模板文件到目标目录,目标目录就是用户当前执行命令行的目录,所以这里写一个copy函数。

    import ncp from 'ncp'
    import { promisify } from 'util'

    const copy = promisify(ncp)
    // 复制文件
    const copyTemplateToTarget = async (options) => {
    return copy(options.templateDir, options.targetDir, {
    clobber: false // 直接覆盖已有文件
    })
    }

    ...
    try {
    // 检查文件是否存在于当前目录中
    await access(templateDir, fs.constants.F_OK);
    } catch (e) {
    console.error('%s Invalid template name', chalk.red.bold('ERROR'));
    process.exit(1);
    }
    复制代码

    在真正执行copy函数前,还得考虑模板文件是否存在,如果子弹都没有,那就直接退出了。

    预设的模板根目录要和上面的选项能够对应起来,模板内容这里就不提供了,可以自行定义。

    初始化git仓库

    git仓库初始化一般直接运行 git init 即可,所以这里也按着思路,直接利用 execa 来运行git命令行,这里使用async语法让执行逻辑更加清晰:

    import execa from 'execa'

    const initGit = async (options) => {
    const result = await execa('git', ['init'], {
    cwd: options.targetDir
    })
    if (result.failed) {
    return Promise.reject(new Error('Failed to initialize git'))
    }
    return
    }
    复制代码

    安装npm依赖

    前端项目初始化后,可以做的更加自动化一点,直接帮用户把npm包也给安装了,这里也有个现成的工具叫 pkg-install ,支持yarn安装,promise的用法。

    import { projectInstall } from 'pkg-install';

    await projectInstall({
    prefer: 'yarn',
    cwd: options.targetDir
    })
    复制代码

    串行任务

    定义好了各个选项对应的功能后,就要把配置对应的功能接上,这里用 listr 进行任务管理,最终的执行函数如下:

    export default async function createSpaApp(options) {
    options = {
    ...options,
    targetDir: options.targetDir || process.cwd()
    }
    // 预设模板目录
    const templateDir = path.resolve(
    new URL(import.meta.url).pathname,
    '../../templates',
    options.template
    )
    options.templateDir = templateDir;

    try {
    // 检查文件是否存在于当前目录中
    await access(templateDir, fs.constants.F_OK);
    } catch (e) {
    console.error('%s Invalid template name', chalk.red.bold('ERROR'));
    process.exit(1);
    }

    const tasks = new Listr([
    {
    title: 'Copy project files',
    task: () => copyTemplateToTarget(options)
    },
    {
    title: 'Initialize git',
    task: () => initGit(options),
    enabled: () => options.git
    },
    {
    title: 'Install dependencies',
    task: () =>
    projectInstall({
    prefer: 'yarn',
    cwd: options.targetDir
    })
    ,
    skip: () => {
    !options.runInstall
    ? 'Pass --install to automatically install dependencies'
    : undefined
    }
    }
    ])

    await tasks.run()
    console.log('%s Project ready', chalk.green.bold('DONE'));
    return true
    }
    复制代码

    listr提供了页面的进度显示,每一个步骤都会有个loading的效果

    ae04e1cf2748144eb2a134973435ea77.png

    最终的效果就是下面的样子,有点低配版 create-react-app 那味儿了

    6495c44831f575ba553bb6d7121abf0d.png

    结束

    CLI工具不一定只能拿来做脚手架的事情,还能干很多自动化运维、语法解析、文件监听等等便于开发的事情,这里只是简单通过一个demo来演示其中的原理。

    4a2ad717dc5960f1567e0eb35a468a23.gif

    展开全文
  • 项目要求: 请按文档 使用 selpg 章节要求测试你的程序 请使用 pflag 替代 goflag ... “-dXXX” 实现,请自己查 os/exec 库,例如案例 Command,管理子进程的标准输入和输出通常使用 io.Pipe,具体案例见 Pipe ...
  • 如何打造自己CLI

    2019-01-28 14:01:40
    有哪些CLI? Vue-cli Gulp create-react-app ...根据动态命令更方便的生成开发环境。 团队协同,效率高。 我们要达到的设计? Node-Simple-BFF-Architecture init node-BFF Node-Simple-BFF-A...
  • 工作中接到新项目,开发前都需要先规划项目目录,然后一个个创建文件,搭建sass编译环境,下载jquery,Swiper等类库......本文以自己的my-cli为例,将开发到发布过程完整记录下来,看完本文,你将学会如何从零开发...
  • "build-npm": "vue-cli-service build --target lib --name mynpm ./src/index.js" }, "main": "dist/mynpm.common.js", "private": false, "license": "MIT", "repository": { "type": "git", "url": ...
  • jspicl CL​​I是一个命令行工具,可简化JavaScript中PICO-8游戏的开发。 特征: 带有自己的一套构建管道,因此您不需要一个。 通过JavaScript转换为PICO-8 Lua的。 摇树可防止包括未使用的代码并增加令牌数。 ...
  • 在某些情况下需要在 PHP 语言的基础上进行扩展,那么就需要通过 PHP 底层提供的数据结构和接口来开发 PHP 扩展,从而来补充或扩展 PHP 语言,使之更加的强大。当然了,PHP 本身就已经集成了一些基本的、强大的、优秀...
  • [vue-cli]不用vue-cli,你自己有搭建过vue的开发环境吗?流程是什么? 基本概念 首先先了解先webpack的基本概念,webpack属于一个构建工具,主要有mode、entry、output、loader、plugin这几部分组成。 目标 本文会带...
  • 从0到1搭建一个自己的脚手架 顾名思义,脚手架就是帮助我们配置一些环境、工具,能够让我们方便的直接开始开发,专注于我们的业务,不用花时间去配置开发环境。...接下来我们就要实现一个属于自己cli脚手架……
  • 有哪些CLI?Vue-cliGulpcreate-react-appwebpackyeomanexpress-generator...为什么需要CLI?...根据动态命令更方便的生成开发环境。团队协同,效率高。我们要达到的设计?zmz-vuecli init demozmz...
  • CLI 命令行实用程序开发基础 任务: 使用 golang 开发 开发 Linux 命令行实用程序 中的 selpg 提示: · 请按文档 使用 selpg 章节要求测试你的程序 · 请使用 pflag 替代 goflag 以满足 Unix 命令行规范, ...
  • Node.js开发-stacks-cli

    2019-08-09 15:18:08
    事实上,我知道已经有很好的名为Wappalyzer的Chrome扩展,但我仍然想为自己制作一个CLI工具。
  • vue-cli3快速开发

    千次阅读 2018-11-19 09:47:42
    更多详见:https://dfairy.github.io/dfairyblog/document/documents/vue-cli3%E6%95%99%E7%A8%8B.html 1、升级到vue-cli3版本 npm install -g @vue/cli 2、查看版本 ...4、选择自己所需要...
  • 本课程基于ES6来学习Vue的整个API,其中包含Vue基础API、Vue组件化开发、Vue组件通信、官方脚手架Vue-cli3的使用、Vue-devtools的使用 、element-ui第三方组件的使用、手把手带你打造自己的表单组件、Vue核心插件之...
  • 作业描述:CLI 命令行实用程序开发 作业中提供了两种语言,一种语言是c的,一种语言是python。这两种语言我都略懂一点,但却深感自己学的不深,这里尝试使用C来写。 前期准备 CLI CLI(Command Line Interface)实用...
  • CloudFormation CLI(cfn)允许您编写自己的资源提供程序和模块,以供CloudFormation使用。 用法 文献资料 可以在站点上找到CloudFormation CLI的主要文档。 安装 可以使用Python软件包索引(PyPI)中的安装此工具...
  • 基于quagga开源包的嵌入式CLI开发

    千次阅读 2013-11-05 10:23:58
    做嵌入式开发的筒子们大部分会遇到CLI开发的问题。如何开发一个用户友好又高端大气上档次的CLI往往让我们头疼不已。  因为工作的原因,有幸接触到... 下面开始制作我们自己CLI吧:(以下操作环境均为ubuntu10.04)
  • 用vue-cli脚手架开发APP的步骤

    千次阅读 2019-07-30 16:37:52
    本文主要记录vue-cli脚手架开发app的步骤,如果还未安装vue-cli的请查看vue-cli官方文档有详细过程。 项目地址:vue-cli-demo 效果 点击链接实现界面跳转,下方底部可以改成导航栏,中间内容自己修改。 步骤 1....
  • 用Nodejs开发命令行工具(cli)入门

    千次阅读 2018-12-04 22:06:48
    日常前端开发中,经常见到各种cli,如一行命令帮你生成vue项目模板的vue-cli。编写合适的命令行工具也可以快速构建出适合自己项目的模板。 前言 node cli的本质其实就是执行node脚本。 先安装好node及npm: Nodejs...
  • CLI 命令行实用程序开发基础开发实践目的要求环境配置代码实现参数结构体selpg_args参数获取函数参数检查输入读取输出文件读写 开发实践 目的 使用 golang 开发开发 Linux 命令行实用程序中的 selpg 要求 请按文档...
  • 自动生成组件代码—— Vue CLI 插件开发实战 前言 近期工作的过程中跟Vue CLI的插件打交道比较多,想了想自己在学校写项目的时候最烦的就是项目创建之后手动创建组件/页面和配置路由,于是突发奇想决定写一个...
  • vue.js有著名的全家桶系列,包含了vue-router,vuex, vue-resource,再加上构建工具vue-cli,就是...作用:不必自己手动配项目环境,提供好基本的项目结构。npm install -g vue-cli验证是否安装成功vue –version用v...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,666
精华内容 666
关键字:

自己开发cli