命令行工具开发总结

# 命令行工具开发总结

  • cli工具,一般用来帮助团队提升开发效率,将一些日常工作中的频繁操作通过命令行工具实现自动化,比如创建项目、组件、打包、发布等等。
  • 比如vuevue-cli, angularangular-cli, reactcreate-react-app.
  • 对于一个团队来讲,开源工具提供的模板不一定是完全适用的,需要做一些个性化的定制,项目模板和组件模板需要自己定制,打包、发布命令也需要自己定制。
  • 可以选择基于开源工具做二次封装,也可以完全重写。

# 常用插件

  • 命令行交互使用 npm社区插件 commander
  • 提供用户选择插件使用 inquirer,与用户进行一些简单的交互以确定项目的一些细节配置。
  • 从github下载模板使用插件 download-git-repo
  • 模板文件流处理: metalsmith
  • 模板引擎处理: Handlebars
  • 可以执行shell命令的插件:shelljs

# commander

  • 这个包大家都非常熟悉了,有一些坑需要注意。

# 命令:command

  • 在执行命令的时候,有两种方式,一种可执行文件的方式,一种是在代码中直接编写。
  • 当使用第一种方式的时候,.command()带有描述参数时,就意味着使用独立的可执行文件作为子命令。需要两个参数,和提供一个文件,比如你的命令行工具叫做my-tool,那么对应的文件名就是my-tool-init。当然,也可以通过配置选项executableFile可以自定义名字。如果该命令需要支持全局安装,请确保有对应的权限,例如755
  • 第二种方式,使用的参数不一样,需要提供一个函数回调,program.action((source, destination) => {// do something})

# 参数

  • 在传参的时候,可以使用必选<params>或者可选[params]
  • 在参数后面加上...代表可变参数。

# 其他

  • 帮助信息是 Commander 基于你的程序自动生成的,默认的帮助选项是-h,--help
  • program.parse的第一个参数是要解析的字符串数组,也可以省略参数而使用process.argv
  • 最新版的commander,要求的 Node 版本应不低于v12。
  • 官方提供一些不再推荐使用的功能 (opens new window)

# shelljs

  • Shelljs本质就是基于node的一层命令封装插件,常用的方法:
  • exec(command [, options] [, callback]),执行传入的命令,默认是同步执行。
  • rm([options,] file [,file ...]), 删除目录。
  • cp([options,] source_array, dest), 复制文件到某个目录。

# 核心功能

  • 一个基本的脚手架工具的基础功能包括:创建项目、项目打包、项目发布等等。
  • 其他丰富的功能,也是基于上面基础功能进行扩展的。

# 创建项目

  • 创建之前可以区分类型,比如组件,还是项目。项目的话,又可以根据不同的配置和业务形态进行拉取不同的模板。
  • 拉取模板时会提问拉取模板类型、在当前目录创建的文件类型、项目名称、项目描述等
  • 通过inquirer插件,来获取用户在终端的选项。
  • 伪代码如下
// 预设配置项问题
const questions = [{
	name: 'templateType',
	message: '选择项目模板',
}, {
	name: 'projectName',
	message: '请输入项目名称'
}]

// 收集用户配置项
const options = collectOptions()

// 判断本地有无存在相同的项目名称
if(!fs.existsSync(projectName)) {
	// 根据选项下载模板
	download(templateType, projectName) 

	// 执行install
	try {
        const cmd = `cd ${projectName} && npm install`;
        shelljs.exec(cmd);
    } catch () {
        // 异常处理
    }
} else {
	// 提示已存在同名项目
}

# 构建项目

  • 在构建项目之前,可以根据不同配置来拼接build命令,比如:
    • 应用类型:单页应用、多页应用
    • 使用的打包工具:webpack, vite, vue-cli
  • 如果嫌每次打包选择比较麻烦,可以将打包配置存储起来,比如放到package.json中,或者单独作为一个配置项放到模板文件中,在执行build之前直接读取配置即可。
  • vue cli3为例,我们的build命令为npx vue-cli-service build

# 模板结构

# Vue 2.0 ts 模板

  • 待完善

# 获取多页应用配置

//获取多页应用配置
const getPagesConfig = () => {
    //定义多页路由配置空对象
    let pages = {};
    //定义基础路径
    let baseUrl = "src/pages";
    //pages路径
    let pagesPath = resolve(baseUrl);
    //page下的文件夹列表
    let pagesDirList = fs.readdirSync(pagesPath);
    //迭代page下的文件夹列表[比如 games ...] (文件夹数组)
    pagesDirList.forEach((pagesChildDir) => {
        //pages的子路径
        let pagesChildPath = resolve(`${baseUrl}/${pagesChildDir}`);
        pages[pagesChildDir] = {
            entry: resolve(`${baseUrl}/${pagesChildDir}/main.ts`),
            template: resolve(`${baseUrl}/${pagesChildDir}/index.html`),
            filename: `${htmlBaseUrl}${pagesChildDir}.html`,
            chunks: ["chunk-vendors", "chunk-common", `${pagesChildDir}`]
        }
    });
    return pages;
};

# Vue 3.0 模板

  • 待完善

# 参考