Bootstrap

「从0到1如何快速实现cli工具」

大家好,我是速冻鱼🐟,一条水系前端💦,喜欢花里胡哨💐,持续沙雕🌲欢迎小伙伴们加我微信:拉你进群,一起讨论,期待与大家共同成长🥂

阅读本文 🦀

1.您将了解到什么是CLI

2.您将了解到什么是Docker

3.您将了解到什么是NodeJs

4.您将了解到如何从零到一快速实现一个CLI工具

5.您将了解到如何在我们的项目中使用自己编写的CLI工具

本文章对应项目仓库地址 :🎄

前言 🌵

造这个是因为公司之前的项目用的docker镜像生成工具🔧是基于和来实现的,显然在前端项目中出现这种东西不太美观,而且项目结构会比较混乱,新接触项目的小伙伴看见项目里这些看不懂的东西就是、,所以就基于环境来重新实现我们的docker镜像生成CLI工具吧^_^

前置知识 🐳

什么是CLI?

是一个,它接受文本输入以执行操作系统功能。简单得来说就是可以通过命令行来执行的程序,不同于我们的图形操作界面而已。例如我们比较熟悉的CLI工具有、、等等都是我们比较熟悉的CLI工具。我们通过CLI执行操作系统功能,最主要的作用我认为可以让将日常繁琐且重复的开发步骤简化并抽象为一个CLI工具,帮助我们简化开发,

什么是Docker?

docker是一项操作系统层面的,本文重点不在介绍docker,说人话docker就是,我们在docker中运行我们的程序(比如、等等)。

什么是NodeJs?

我认为知道以下两点就够了

  • Node.js 是一个与的 。 它是一个可用于几乎任何项目的流行工具!

  • Node.js 在运行 (Google Chrome 的内核)。

需求 💻

  • Web静态站点项目生成基于Nginx的Docker镜像文件

  • Node应用项目生成基于Node的Docker镜像文件

  • Web静态站点+Web服务器应用项目生成基于Node的Docker镜像文件

开发思路 ⭐

下面我将带领各位小伙伴一起实现我们的第一个需求,对生成基于的,其他需求实现类似,就不一一实现了。

1. 首先是初始化项目啦

初始化我们的CLI项目就叫吧

2. 如何让CLI工具在项目中运行呢

2.1 配置package.json

这里一定要在package.json文件中配置,为你这个指定执行的入口文件

//、、、
  "bin": {
    "craft": "bin/craft.js"
  },
  "author": "sudongyu",
  "license": "ISC",
  "dependencies": {
    "commander": "^8.2.0",
    "cpy": "^8.1.2",
    "figlet": "^1.5.2",
    "make-dir": "^3.1.0",
    "process": "^0.11.10",
    "shelljs": "^0.8.4"
  },
//、、、
}

2.2 在项目中创建bin文件夹并书写我们的入口文件

2.3 编写我们的入口craft.js文件

一定要在开头指定我们代码的执行环境这里我们指定为node环境

#!/usr/bin/env node
import {cwd} from 'process';
import path from "path";
import {Command} from 'commander/esm.mjs';
import {createRequire} from "module";
import {frameworkDockerTask, nginxDockerTask, nodeDockerTask} from './tasksUtiles/index.js'
//踩坑,在node中使用esm必须完成路径.js不能简写

3. 获取package.json文件对象信息

这里我们获取调用CLI工具项目的package.json 文件对象获取我们需要的信息,必须当前项目名称类型等等,方便我们后边的代码编写

const require = createRequire(import.meta.url);
//获取PackgeJson文件信息
let pkgManifest = require(path.join(cwd(), 'package.json'));

//获取craft配置信息对象
let craftConfig = pkgManifest?.craft;

4. 使用Commander库来获取命令行参数

使用第三方库Commander可以很方便的获取命令行参数,生成我们的帮助信息命令等等

import {Command} from 'commander/esm.mjs

const program = new Command();

program.option('-d, --docker', 'generate docker image');

program.addHelpText('after', `
Example call:
  $ craft-h --help`);

program.parse(process.argv);

//获取命令行参数
const options = program.opts();

5. 根据命令行参数来生成不同类型的Docker镜像文件

//根据docker命令执行打包docker镜像
if (options.docker) {

    try {
        //1.输出开始打包docker日志
        console.log(`- craft docker running ^_^ !!!!`);
        //2.获取配置文件信息
        switch (craftConfig.buildType) {
            case "web":
                console.log(`
            ###################
            web docker building
            ###################
            `)

                nginxDockerTask(craftConfig.web.distDir)
                break;
            case "node":
                console.log(`
            ####################
            node docker building
            ####################
            `)

                nodeDockerTask()
                break;
            case "lib":

                console.log('node docker building')

                break;

            case "framework":

                console.log(`
            #########################
            framework docker building
            #########################
            `)

                frameworkDockerTask()

                break;

            default :
                console.log('can not find buildType')
        }
    } catch (e) {
            console.error(`
            ==========================
            craft docker faild ! ! !
            ==========================
            `,e)
    }
}

6. 生成基于nginx的Docker镜像文件

这里我们以web静态站点项目为例,所以我们要生成一个基于nginx的Docker镜像,我们就需要生成nginx的配置文件,在dockerFile引入等。

  • 首先我们需要将web项目打包好的dist目录复制到build目录下 (这里我们会临时创建一个build目录用来放置打包好的dist文件和nginx相关配置文件,方便我们后续生成镜像)

  • 在build目录下生成nginxConfig配置文件

  • 生成基于nginx的DockerFile文件(用来生成镜像的文件)

  • 生成胡哨的命令行文字图片(表示我们镜像生成完成了)

async function nginxDockerTask(buildDir = 'dist') {
    //多加一次为空串的判断,防止后边cpy拷贝所有目录
    if(!buildDir)buildDir="dist"

    // Copy buildDir to build/buildDir
    await copyFile(buildDir,'build')

    //生成NginxConfig
    await generateNginxConfig()

    //生成NginxDockerFile
    await generateNginxDockerFile()

    // 生成docker镜像文件
    await generateDockerImage()

    //展示craft图案执行完成
    showFiglet()

}

tips:我们可以使用开源库来拷贝文件,使用来展示文字图片,使用提供的文件操作系统来写入我们的数据

7. 测试我们CLI工具的完整流程

  • 在项目中引入我们编写好的CLI工具并配置文件

{
  "name": "XXX",
  "version": "0.1.0",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "craft-h": "craft -h",//这里就是我们CLI脚本命令
    "craft-docker": "craft --docker"//这里就是我们CLI脚本命令
  },
  //我们的CLI工具需要的配置信息
  "craft": {
    "buildType": "framework",
    "web": {
      "distDir": ""
    },
    "node": {
      "command": ""
    },
    "framework": {
      "web": "",
      "server": ""
    }
  },
  //导入我们CLI工具库
  "devDependencies": {
    "@imf/craft-client": "^1.0.1"
  }
}

  • 中执行我们的脚本命令

npm run craft-docker

成功在看见我们花里胡哨的,表示镜像成功生成

在Docker DeskTop软件中查看我们的镜像并运行

镜像成功运行

总结 🍁

到这我们的就完成啦🌈,通过编写可以提高项目,将的工作进行,希望每个小伙伴都能够自己动手实现一个提升效能的,一起感受它的魅力吧🤹‍♂️~

craft-client源代码仓库地址:👣

参考文献 📚

结束语🌞

那么我的就结束了,文章的目的其实很简单,就是对日常工作的,输出一些觉得对大家有用的东西,菜不菜不重要,但是热爱🔥,希望通过文章认识更多志同道合的朋友,如果你也喜欢,欢迎加我,一起,一起。

github🤖:

个人博客👨‍💻:

vx👦:sudongyuer

伙伴们,如果喜欢我的给🐟🐟点一个赞👍或者关注➕都是对我最大的支持。