美文网首页
node编写命令行工具

node编写命令行工具

作者: xurna | 来源:发表于2022-11-23 14:31 被阅读0次

    为了脚本的可复用性,可以把平时用到的一些便捷的脚本做成命令行的方式,使用时只需要安装对应的npm包就可以了。

    环境

    • 系统:macOS系统
    • 依赖:node

    过程

    新建js可执行文件

    // index.js
    #!/usr/bin/env node
    console.log('hello world');
    

    #!/usr/bin/env node:让系统自动去环境设置寻找node目录,再调用对应路径下的解释器程序,该行必不可少。

    命令行直接执行:

    ➜ node index.js
    

    上面执行命令前面还需指定node,#!/usr/bin/env node的优势没利用起来,利用自动找node执行程序需要修改文件权限。默认文件权限是644(-rw-r--r--),修改文件的权限为744(-rwxr--r--)。

    ➜ chmod 744 index.js
    

    现在,可以直接用对应路径的文件名就可以执行了。

    ➜ ./index.js
    hello world
    

    这样如果文件路径很长的时候执行脚本也简洁,还是没有直接使用命令行这么方便,进一步使用npm link

    • 首先,命令行执行npm init,创建一个package.json文件。

    设置bin:将bin下的命令作为全局命令安装到node_modules中,此时可以直接运行git-auto-commit命令,不需要使用node 文件名或者对应路径文件名的方式执行。

    // package.json
    {
      "name": "cute-git-tools"
      "bin": {
        "git-auto-commit": "./index.js"
      },
    }
    
    • 执行npm link:本地开发npm模块时,将npm模块链接到对应的运行项目中去,方便地对模块进行调试和测试。
      • 具体用法:
        1. 项目和模块在同一个目录下,可以使用相对路径,这样它映射的是目录名称:npm link ../module
        2. 项目和模块不在同一个目录下示例
        • 先cd到模块目录,npm link,会取package-name进行映射,创建全局link
        • 然后cd到项目目录(引用模块的地方),npm link 模块名(package.json中的name包名和package.json中bin中命令都会隐射)
          cd ~/projects/node-redis    # go into the package directory
          npm link                    # creates global link
          cd ~/projects/node-bloggy   # go into some other package directory.
          npm link redis              # link-install the package
          
        1. 解除link
        • 解除项目和模块link,项目目录下,npm uninstall 模块名
        • 解除模块全局link,模块目录下,npm uninstall -g 模块名

    在项目根目录下执行:npm link,可以看到本地bin下的git-auto-commit命令映射到lib/node_modules/cute-git-tools/bin/index.js中,而lib/node_modules/cute-git-tools隐射到开发目录,这样,只要开发目录修改,执行命令行时就同步执行修改过的代码了,不用手动安装新的npm包,方便本地调试。

    audited 39 packages in 1.375s
    
    5 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities
    
    /usr/local/bin/git-auto-commit -> /usr/local/lib/node_modules/cute-git-tools/bin/index.js
    /usr/local/lib/node_modules/cute-git-tools -> /Users/xxx/project/git-auto-commit
    
    • 执行后npm link后,建立映射关系连接,就可以直接用bin下的模块名直接执行命令了。
    git-auto-commit
    

    编写命令行脚本

    编写命令行脚本有几个模块可以选择使用:

    process.argv

    process.argv返回一个数组,数组前两位是固定的,分别是node程序的路径和脚本存放的位置,从第三位开始才是额外输入的内容。

    // index.js
    #!/usr/bin/env node
    console.log(process.argv);
    

    执行:

    ./index.js --name=hello
    

    输出:

    [
      '/usr/local/bin/node',
      '/Users/xxxx/project/git-auto-commit/index.js',
      '--name=hello'
    ]
    

    yargs 模块

    yargs通过解析参数和生成优雅的用户界面来构建交互式命令行工具。
    安装:

    npm install --save yargs
    

    修改脚本:

    #!/usr/bin/env node
    const yargs = require('yargs/yargs')
    const { hideBin } = require('yargs/helpers')
    const argv = yargs(hideBin(process.argv)).argv
    console.log(hideBin(process.argv))
    console.log(argv)
    console.log('hello', argv.name)
    

    执行:

    ./index.js --name=world A
    

    输出:

    [ '--name=world', 'A' ]
    { _: [ 'A' ], name: 'world', '$0': 'index.js' }
    hello world
    

    hideBin相当于process.argv.slice(2)yargs模块的作用就是美化得到的命令行参数,获取参数为一个对象,方便取值。argv 对象有一个下划线(_)属性,可以获取非连词线开头的参数。

    child_process

    脚本可以通过node下面的 child_process 模块新建子进程,从而执行 Unix 系统命令。

    #!/usr/bin/env node
    const name = process.argv[2];
    const exec = require('child_process').exec;
    const child = exec('echo hello ' + name, function(err, stdout, stderr) {
      if (err) throw err;
      console.log(stdout);
    });
    

    执行:

    ./index.js world
    

    输出:

    hello world
    

    shelljs 模块

    shelljs可以兼容在(Windows/Linux/macOS)系统中执行Unix shell命令。

    安装:

    npm install --save shelljs
    

    shelljs 模块重新包装了Unix shell命令,使其在都可在Windows/Linux/macOS系统使用。

    #!/usr/bin/env node
    const name = process.argv[2];
    const shell = require("shelljs");
    shell.exec("echo hello " + name);
    

    执行:

    ./index.js world
    

    输出:

    hello world
    

    shell.exec返回Object类型

    [String: '* feature/nodecli\n  master\n'] {
      stdout: '* feature/nodecli\n  master\n',
      stderr: '',
      code: 0,
      cat: [Function: bound ],
      exec: [Function: bound ],
      grep: [Function: bound ],
      head: [Function: bound ],
      sed: [Function: bound ],
      sort: [Function: bound ],
      tail: [Function: bound ],
      to: [Function: bound ],
      toEnd: [Function: bound ],
      uniq: [Function: bound ]
    }
    

    readline 模块

    node中的readline模块提供了用于从可读流(例如 process.stdin)每次一行地读取数据的接口。

    示例:可以用来读取用户输入

    #!/usr/bin/env node
    const readline = require('readline');
    
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    });
    
    rl.question('What do you think of Node.js? ', (answer) => {
      console.log(`Thank you for your valuable feedback: ${answer}`);
      rl.close();
    });
    

    执行:

    ./index.js
    

    输出:

    What do you think of Node.js? Nice
    Thank you for your valuable feedback: Nice
    

    inquirer 模块

    inquirer模块跟 readline 模块有点类似,但是inquirer模块提供更加丰富的问询模式,例如,单选,多选,用户输入等,通过回调的方式处理回答的内容。

    npm install --save inquirer
    

    脚本

    #!/usr/bin/env node
    const inquirer = require('inquirer')
    inquirer
      .prompt([{
        type: 'input',
        message: 'input a question: ',
        name: 'answer'
      }]).then((answers) => {
        console.log(answers)
      })
      .catch((error) => {
        console.log(error)
      });
    

    chalk 模块:命令行样式美化

    chalk用于美化输出的命令行颜色等样式
    安装:

    npm install --save chalk
    

    示例:打印输出

    #!/usr/bin/env node
    const chalk = require('chalk')
    
    console.log(chalk.blueBright('blueBright color'))
    console.log(chalk.greenBright('greenBright color'))
    console.log(chalk.redBright('redBright color'))
    console.log(chalk.yellow('yellow color'))
    

    输出:


    image.png

    更多模块

    1. ora:优雅的终端loading展示。
    2. Inquirer:一组常见的交互式命令行用户界面。
    3. commander:node.js 命令行界面的完整解决方案。

    发布npm包

    1. 登录npm账号,如果没有账号,则去npm网站注册一个,或者使用npm adduser命令,提示输入账号,密码和邮箱,然后将提示创建成功,如果已有账号,则用以下命令登录。查看是否登录:npm whoami
    npm login
    // 如果npm login或者npm adduser时报如下错误:npm ERR! 404 Registry returned 404 for PUT on undefined
    // 则更换npm源
    npm set registry https://registry.npmjs.org/
    // 或者更新npm至最新版本
    npm install -g npm
    
    1. 修改npm源,发布前,如果自己之前用的是淘宝镜像源,则需要改成npm源
    npm set registry https://registry.npmjs.org/
    
    1. 发布
    npm publish
    

    4.有需要则恢复淘宝镜像源

    npm config set registry https://registry.npm.taobao.org
    

    更多阅读

    相关文章

      网友评论

          本文标题:node编写命令行工具

          本文链接:https://www.haomeiwen.com/subject/xhpnxdtx.html