这是系列文章`前端脚手架实现`的第一篇,主要讲解脚手架工具中的核心模块命令行参数解析功能的实现,重点讲解 Node 模块 [commander]()的使用。

在前端开发中我们已经接触过各种各样的脚手架工具,从Yeomanvue-clidva-cli等,这几篇文章将讲解脚手架工具的核心功能以及具体实现细节,本文探讨哪些功能呢?我们先随便拿一个现成的脚手架工具vue-cli来作为参考。

当我们通过npm install -g @vue/cli 来全局安装 @vue/cli之后,就可以在终端中使用 vue 指令了。

wendingding:vue-test wendingding$ vue --version
@vue/cli 4.3.1
wendingding:vue-test wendingding$ vue --help
Usage: vue <command> [options] Options:
-V, --version output the version number
-h, --help output usage information Commands:
create [options] <app-name> create a new project powered by vue-cli-service
add [options] <plugin> [pluginOptions] install a plugin and invoke its generator in an already created project
invoke [options] <plugin> [pluginOptions] invoke the generator of a plugin in an already created project
inspect [options] [paths...] inspect the webpack config in a project with vue-cli-service
serve [options] [entry] serve a .js or .vue file in development mode with zero config
build [options] [entry] build a .js or .vue file in production mode with zero config
ui [options] start and open the vue-cli ui
init [options] <template> <app-name> generate a project from a remote template (legacy API, requires @vue/cli-init)
config [options] [value] inspect and modify the config
outdated [options] (experimental) check for outdated vue cli service / plugins
upgrade [options] [plugin-name] (experimental) upgrade vue cli service / plugins
migrate [options] [plugin-name] (experimental) run migrator for an already-installed cli plugin
info print debugging information about your environment Run vue <command> --help for detailed usage of given command. wendingding:vue-test wendingding$ abc
-bash: abc: command not found

观察上面的终端命令和显示输出,我们总共输入了三个命令

$ vue --version 查看版本信息

$ vue --help 获取帮助信息

$ abc 随意输入的指令,显示command not found该指令不存在。

本文将专注实现上面的功能,假设我们自己实现的脚手架名为Yue-cli那么当我在终端中使用Yue-cli的时候,系统应该认识该指令,且能够获取当前脚手架的版本并能够获取帮助信息,下面给出具体的实现过程。

项目准备

在电脑中新创建文件夹,假设为 Yue-cli ,在该文件夹下面执行下面的命令先做一些准备工作。

npm init -y                         # 初始化package.json
npm install eslint husky --save-dev # eslint是负责代码校验工作,husky提供了git钩子功能
npx eslint --init # 初始化eslint配置文件,用于语法检查
目录结构

参考下面的目录结构来创建文件和文件夹,关键。

.
├── bin
│ └── www <!-- 全局命令执行的根文件 -->
├── node_modules <!-- 安装的包文件 -->
│ ├── @babel
│ ...
│ └── yaml
├── package-lock.json
├── package.json <!-- 元信息文件 -->
├── src
│ └── main.js <!-- 项目入口文件 -->
│── .huskyrc <!-- git hook -->
│── .eslintrc.json <!-- 代码规范校验文件 -->
└── util
└── constants.js <!-- 该文件用于存放公共常量数据 -->
配置和链接

❏ 配置 package.json 校验src文件夹下的代码

"scripts": {
"lint":"eslint src"
}

❏ 配置 husky 文件,当使用git提交前校验代码是否符合规范

{
"hooks": {
"pre-commit": "npm run lint"
}
}

❏ 链接全局包,编写 package.json 文件设置在终端中执行 Yue-cli 时调用 bin 目录下的 www 文件

 "bin": {
"Yue-cli": "./bin/www"
},

bin 目录下面的 www 文件设置使用 main.js 作为入口文件,并且以 node 环境 执行此文件

#! /usr/bin/env node
require('../src/main.js');

❏ 链接包到全局环境下使用

npm link

到现在这一步,我们就已经可以成功的在命令行中使用Yue-cli命令了,当在终端中执行Yue-cli命令的时候其内部会执行main.js文件,如果我们在该文件中加上一行打印代码console.log("hello Yue-cli"),那么在终端中可以看到对应的输出。

使用 commander 解析命令行参数

commander 模块可以帮助我们自动的生成 help 信息,解析选项参数大家可以点击到npmjs网站查看包模块的详细情况。

先在系统中安装 commander 模块

npm install commander

在入口文件 main.js 文件中引入该模块并测试

const program = require("commander")

// process.argv就是用户在命令行中传入的参数
program.version('1.0.1').parse(process.argv);

此时,我们终端使用 Yue-cli --help 或者是 Yue-cli --version 就能看到对应的提示信息。

wendingding$ Yue-cli --version
1.0.1 wendingding$ Yue-cli --help
Usage: Yue-cli [options] Options:
-V, --version output the version number
-h, --help display help for command

注意:脚手架的这个版本号应该使用的是当前cli项目的版本号,我们需要动态的来获取,具体实现方式是直接把package.json 文件中的 version 字段值导入到main.js文件中直接使用即可。

 const { name, version } = require("../package");

另外,当我们使用脚手架工具的时候,往往不同的指令会对应不同的功能,譬如vue create app的作用是创建项目,而vue ui的作用是开启一个服务以 UI 界面的方式来创建项目,也就是说不能的 命令 它的功能、别名以及使用示例这些信息都是不同的,如何实现呢?

commander 模块我为了提供了对应的方法,下面给出具体的示例(演示使用,实际功能暂欠缺)。

    /* main.js 文件的内容 */
/* 0.导入模块 */
const program = require("commander") /* 导入常量(package 包中的名称和版本号) */
const { name, version } = require("../package"); /* 1.Yue-cli crete */
program
/* 命令的名称 */
.command("create")
/* 命令的别名 */
.alias("c")
/* 命令的描述 */
.description("create a project whit Yue-cli....")
/* 该命令的具体功能(动作) */
.action(() => {
console.log(`执行 action-> create`);
}); /* 2.Yue-cli config */
program
.command("config")
.alias("conf")
.description("config info....")
.action(() => {
console.log(`执行 action-> config`);
}); /* 3.Yue-cli xxx (其它未定义指令) */
program
.command("*")
.alias("")
.description("command not found")
.action(() => {
console.log(`执行 action-> nothing`);
}); /* 4.示例信息 */
const examples = [
"Yue-cli create <project-name>",
"Yue-cli config get <k>",
"Yue-cli config set <k> <v>"
]; // 5.监听用户的help 事件
program.on('--help', () => {
/* 当终端输入 Yue-cli --help指令的时候打印nExamples信息 */
console.log('\nExamples:');
examples.forEach(example => console.log(` ${example}`))
}); /* 6.版本信息 + 命令行参数解析 */
program.version(`version = ${version}`).parse(process.argv);

我们来看看此时,我们的工具拥有了哪些功能?

wendingding$ Yue-cli --help
Usage: Yue-cli [options] [command] Options:
-V, --version output the version number
-h, --help display help for command Commands:
create|c create a project whit Yue-cli....
config|conf config info....
* command not found
help [command] display help for command Examples:
Yue-cli create <project-name>
Yue-cli config get <k>
Yue-cli config set <k> <v> wendingding$ Yue-cli --version
version = 1.0.1 wendingding$ Yue-cli create myapp
执行 action-> create wendingding$ Yue-cli config
执行 action-> config wendingding$ Yue-cli c app
执行 action-> create

写到这里,脚手架工具的基本提示功能就已经实现了,但代码较长且脚手架的指令肯定不止 createconfig 这么两个,因此这里适当调整下代码结构让其可维护性更高一些。

    /* main.js 文件的内容 */
/* 导入模块 */
const program = require("commander");
/* 导入常量(package 包中的名称和版本号) */
const { name, version } = require("../util/constants"); /* 组织映射结构 */
const actions = {
create: { // 项目创建(初始化)指令
description: 'create project with Yue-cli',
alias: 'c',
examples: [
'Yue-cli create <project-name>',
],
},
config: { // 设置项目配置文件指令
description: 'config info',
alias: 'conf',
examples: [
'Yue-cli config get <k>',
'Yue-cli config set <k> <v>',
],
},
'*': {
description: 'command not found',
alias: '',
examples: [],
},
}; Object.keys(actions).forEach((action) => {
program
/* 命名的名称 */
.command(action)
/* 命名的别名 */
.alias(actions[action].alias)
/* 命令的描述信息 */
.description(actions[action].description)
/* 命令的任务(功能) */
.action(() => { // 动作
console.log(`执行 action->`, action);
});
}); // 监听用户的help 事件
program.on('--help', () => {
console.log('\nExamples:');
Reflect.ownKeys(actions).forEach((action) => { actions[action].examples.forEach((example) => {
console.log(` ${example}`);
});
});
}); /* 版本信息 + 命令行参数解析 */
program.version(`version = ${version}`).parse(process.argv);

前端开发系列132-进阶篇之脚手架Yue-cli的实现01-commander模块的更多相关文章

  1. openlayers5-webpack 入门开发系列一初探篇(附源码下载)

    前言 openlayers5-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载 ...

  2. leaflet-webpack 入门开发系列一初探篇(附源码下载)

    前言 leaflet-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载地址 w ...

  3. 【Windows10 IoT开发系列】配置篇

    原文:[Windows10 IoT开发系列]配置篇 Windows10 For IoT是Windows 10家族的一个新星,其针对不同平台拥有不同的版本.而其最重要的一个版本是运行在Raspberry ...

  4. ESP8266开发之旅 进阶篇② 闲聊Arduino IDE For ESP8266烧录配置

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. 【webpack 系列】进阶篇

    本文将继续引入更多的 webpack 配置,建议先阅读[webpack 系列]基础篇的内容.如果发现文中有任何错误,请在评论区指正.本文所有代码都可在 github 找到. 打包多页应用 之前我们配置 ...

  6. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  7. 旨在脱离后端环境的前端开发套件 - IDT Server篇

    IDT,一个基于Nodejs的,旨在脱离后端环境的前端开发套件,目的就是能让前端开发完全脱离后端的环境,无论后端是什么模板引擎(主流),都能应付自如. IDT主要包括两大部分:Server + Bui ...

  8. 前端开发【第2篇:CSS】

    鸡血 样式的属性多达几千个,但别担心,按照80-20原则,常用的也就几十个,你完全可以掌握它. Css初识 HTML的诞生 早期只有HTML的时候为了让HTML更美观一点,当时页面的开发者会把颜色写到 ...

  9. [置顶]【实用 .NET Core开发系列】- 导航篇

    前言 此系列从出发点来看,是 上个系列的续篇, 上个系列因为后面工作的原因,后面几篇没有写完,后来.NET Core出来之后,注意力就转移到了.NET Core上,所以再也就没有继续下去,此是原因之一 ...

  10. openlayers4 入门开发系列之风场图篇

    前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...

随机推荐

  1. Flutter 2025 年产品路线图发布

    每一年 Google Flutter 团队都会发布一份产品路线图,包括 Flutter 框架和 Dart 编程语言,让开发者能够了解官方团队的优先事项,并据此做出自己的计划安排. 产品路线图也会随着客 ...

  2. flowable任务监听器和java-service依赖注入问题

    前言 1. Flowable中Java服务任务的依赖注入方法,比如使用Spring的@Autowired或构造函数注入,并确保服务任务类由Spring管理. 2. 流程引擎配置中启用依赖注入和表达式解 ...

  3. 7 个最近很火的开源项目「GitHub 热点速览」

    可能很多人昨天都刷到了消息:GitHub 抽风,导致中国区未登录的用户无法访问,现在问题已经修复. 看到这个消息时,我的第一反应也是"被制裁了?"从震惊到平静,不过短短几分钟,随即 ...

  4. ESP-IDF教程2 GPIO - 输入、输出和中断

    1.前提 1.1.基础知识 1.1.1.GPIO 分类 ESP32 系列芯片按照 GPIO 特殊的使用限制分类,可以将其分为如下几类: GPIO PIN GPI PIN Strapping PIN S ...

  5. 里程碑:MCP星球作为国内首个中文MCP社区和MCP工具平台,突破7000个MCP服务!

    随着人工智能技术的快速发展,越来越多的开发者开始使用模型上下文协议(Model Context Protocol,简称MCP)来优化大模型与外部工具的交互.作为首个最大的中文MCP工具市场,MCP星球 ...

  6. nndeploy开源推理框架教程来袭,模型推理全流程,轻松上手,一键精通!

    大家好,我们是 nndeploy 开源团队.我们专注于打造一款端到端的模型推理和部署框架 -- nndeploy,旨在为用户提供高效.便捷.灵活且兼容主流框架的模型推理和部署体验. 此次,我们开发了 ...

  7. 国内首个「混合推理模型」Qwen3深夜开源,盘点它的N种对接方式!

    今日凌晨,通义千问团队正式开源了 Qwen3 大模型,并且一口气发布了 8 个型号,其中包括 0.6B.1.7B.4B.8B.14B.32B 以及 30B-A3B 和 235B-A22B,使用者可以根 ...

  8. gfast工作流2.0发布

    Gfast 是基于 GF (Go Frame) 的后台管理系统,此次为丰富 Gfast 生态而增加工作流,经过长时间的精心研发和严格测试,全新 Gfast 工作流版本现已正式发布! 流程亮点: 1.支 ...

  9. QtWidget项目-仿腾讯QQ音乐

    本博客主要介绍本人写的个人项目 - QtWidget5 仿腾讯QQ音乐项目. 效果演示 项目详情 源码 Gitee地址:https://gitee.com/run-little-peach/my-qq ...

  10. C++ decltype类型推导

    1.decltype介绍 decltype(declare type,声明类型)为C++11 新增的关键字,和auto功能一样,用于在编译期间进行自动类型推导. auto和decltype关键字都可以 ...