铁匠 铁匠
首页
golang
java
架构
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

铁匠

不予评判的专注当下
首页
golang
java
架构
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • nodejs 开发跨平台 cli 工具

    • 如何运行一个 nodejs 脚本
      • 版本1
      • 版本2
    • 工程化开发
      • 基础框架设计
        • 打包&安装
          • 通过 npm 全局安装
          • 打包可执行文件
      fengjx
      2016-04-23
      参考文档
      目录

      nodejs 开发跨平台 cli 工具

      在软件开发中有很多重复性或者是繁琐的工作,通过一些命令行工具可以简化我们的日常工作,提高效率。

      例如:

      • 搭建项目初始开发环境: create-react-app (opens new window), vue-cli (opens new window)
      • http 客户端: httpie (opens new window), curl (opens new window)
      • git 终端 ui 客户端 gitui (opens new window)

      随着 nodejs 的发展,已经在各领域都有完善的生态,使用 nodejs 开发命令行工具也是一个不错的选择

      直接读源码可查看:https://github.com/fengjx/kit.git (opens new window)

      # 如何运行一个 nodejs 脚本

      # 版本1

      // hello.js
      console.log('hello world')
      
      1
      2

      执行

      node hello.js
      
      1

      # 版本2

      // hello.js
      #!/usr/bin/env node
      console.log('hello world')
      
      1
      2
      3

      执行

      chmod 755 hello.js
      ./hello.js
      
      1
      2

      # 工程化开发

      运行一个 nodejs 脚本非常简单,可以和 shell 脚本一样。但是要实现一个完备的功能,我们通常需要依赖第三方类库。写好的工具提供给别人使用就需要一个发布平台。所以使用 npm 来管理项目是个很好的选择。

      除此之外,一个易用的工具,应该给用户提供使用文档,告诉用户有哪些参数可以传,参数含义是什么。如果我们重新开发的话会是一件非常繁琐的事情,好在已经有第三方类库封装了这部分功能。下面是一些封装的比较好的类库。当然也远远不止这些。

      • commander (opens new window) 命令行参数解析
      • inquirer (opens new window) 交互式命令行参数解析
      • shelljs (opens new window) 跨平台 shell 命令
      • pkg (opens new window) node 可执行文件打包工具

      更多第三方类库可查看:https://github.com/huaize2020/awesome-nodejs#命令行工具 (opens new window)

      以下是个简单 demo,更多用法参考官方文档

      bin/hello.js

      #!/usr/bin/env node
      
      const { Command } = require('commander')
      const inquirer = require('inquirer')
      
      const program = new Command()
      program.version('0.0.1')
      
      console.log('hello node cli')
      
      // https://github.com/tj/commander.js
      // 解析命令行参数
      // hello -d -n fengjx
      program.option('-d, --debug', 'debug')
      program.option('-n, --name <type>', 'your name')
      program.parse(process.argv)
      const opts = program.opts()
      
      if (opts.debug) {
        console.log('opts: ', opts)
      }
      
      console.log(`hello: ${opts.name}`)
      
      // https://github.com/SBoudrias/Inquirer.js/tree/master/packages/inquirer/examples
      // 交互式终端
      const questions = [
        {
          type: 'input',
          name: 'username',
          message: "输入账号",
        },
        {
          type: 'password',
          name: 'password',
          message: "输入密码"
        }
      ]
      
      inquirer.prompt(questions).then((answers) => {
        console.log(JSON.stringify(answers, null, '  '))
      })
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42

      执行

      $ node bin/hello.js -d -n fengjx
      hello node cli
      opts:  { debug: true, name: 'fengjx' }
      hello: fengjx
      ? 输入账号 fjx
      ? 输入密码 [hidden]
      {
        "username": "fjx",
        "password": "1024"
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10

      # 基础框架设计

      对于一个命令行工具来说,通常包含以下步骤:

      1. 定义参数
      2. 参数校验&解析
      3. 读取参数,并执行相关逻辑

      我们可以封装一个统一的接口,不同的工具实现对应方法,相同的逻辑全都放到入口函数即可,每个命令只需要实现对应接口的方法。

      接口Cmd定义

      cmd.js

      /**
       * 命令接口
       */
      class Cmd {
      
        /**
         * 命令名称
         *
         * @returns string
         */
        actionName() {
        }
      
        /**
         * 命令参数配置
         * @returns Option[]
         */
        makeOptions() {
        }
      
        /**
         * 业务逻辑
         * @param {*} opts 参数解析结果
         */
        // eslint-disable-next-line no-unused-vars
        exec(opts) {
        }
      }
      
      module.exports = Cmd
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30

      完整项目代码: https://github.com/fengjx/kit (opens new window)

      # 打包&安装

      功能开发好之后,我们需要发布给别人使用,如果是有 node 环境可以直接使用源码安装,也可以直接打包成一个可执行文件,这样别人使用的时候不需要再安装 node。

      # 通过 npm 全局安装

      git clone https://github.com/fengjx/kit.git
      cd kit
      # 安装依赖
      npm i
      # 全局安装
      npm i -g .
      # 测试是否安装成功
      kit --help
      
      1
      2
      3
      4
      5
      6
      7
      8

      # 打包可执行文件

      nodejs 的执行需要依赖 v8 引擎,所以需要 node 环境才能运行,pkg 这个工具可以将 node 环境和代码打包到一起(所以打出来的包会比较大 50M 左右),得到一个可执行文件,可以把文件上传到 cdn 提供别人直接下载使用。

      在package.js中定义了打包命令

      "pkg:mac": "pkg . --targets node14-macos-x64 --output ./.dist/kit-macos-64",
      "pkg:win": "pkg . --targets node14-win-x64 --output ./.dist/kit-win-64",
      "pkg:linux": "pkg . --targets node14-linux-x64 --output ./.dist/kit-linux-64",
      
      1
      2
      3

      不同平台需要指定不同的参数,更多参数可以参考官方文档:https://github.com/vercel/pkg (opens new window)

      通过 npm 打包不同平台下的包

      npm run pkg:mac # pkg:win or pkg:linux
      
      1

      测试

      $ cd .dist
      $ ./kit-macos-64 hello --version
      1.0.0
      
      $ ./kit-macos-64 --help         
      Usage: kit [options] [command]
      
      Options:
        -V, --version     output the version number
        -h, --help        display help for command
      
      Commands:
        hello [options]
        gl-bcl [options]
        help [command]    display help for command
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      #nodejs#cli
      Last Updated: 2024/04/23, 01:30:37
      最近更新
      01
      go-kit学习指南 - 多协议支持
      04-19
      02
      go-kit学习指南 - 中间件
      04-19
      03
      go-kit开发微服务 - 服务注册与发现
      04-19
      更多文章>
      Theme by Vdoing | Copyright © 2016-2024 铁匠 | 粤ICP备15021633号
      • 跟随系统
      • 浅色模式
      • 深色模式
      • 阅读模式