实现一个自定义的vue脚手架

news2024/9/22 23:39:02

开发背景

博客很久没有更新了, 今天更新一个好玩的,等我将vue3的东西彻底搞明白我会更新一个vue3的系列,到时候会更新稍微勤一点,在使用vuecli的时候发现他的脚手架很有意思,用了几年了,但是一直没有好好研究过这个东西是怎么实现的,所以今天就好好的记录一下这玩意怎么实现的,记录的过程中有什么注意事项我也会标明的,当然我会尽可能的写的明白一些,因为这个东西有一些地方不那么好理解,当一个东西不太好理解的时候文章书写的顺序就显的很重要,因为开始的时候如果你就很迷茫,那么你看下去的看动力也就没有了,所以我也是尽可能的从最简单的开始写,相信只要按照文章一点点的来,应该都是没问题的,我文章的顺序就是我自己开发这个功能的顺序,如果有大神觉得我哪里写的有什么问题的话,也可以下方留言,我看到了都会补充说明并表示感谢。文章看起来觉得比较费劲的可以直接移步我的github,源码奉上 源码

先看效果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

实现过程中可能存在的问题
  • 如何获取用户的输入
  • 如果根据用户的输入进行相应的操作
  • 如何自定一个packag.json文件
  • 如何发布到npm

初始化一个package.json

npm init 或者 npm init -y

初始化一个测试文件

#!/usr/bin/env node
console.log("function is success")

特殊说明: #!/usr/bin/env node 这里是必须要加的,如果你实在不理解,那么你可以先这样写,另外就是这行代码必须是第一行,他的前面不可以有任何代码 当然这里也可以解释一下,你可以简单的理解为增加这一行是为了指定用node执行脚本文件。如果想深入理解这个东西,可以看一下大神的介绍Shebang 希望可以有点帮助

运行该文件

node index.js

将node index.js 替换为自定义命令

比如:wlm

我们的目的是,当我们输入 wlm的时候 执行的是node index.js这句话即可

配置package.json

{
  "name": "wlm-cli",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "bin": {
    "wlm":"index.mjs"
  }
}
bin命令 说明

“bin”: {
“wlm”:“index.js”
}

这里的bin就是我们需要使用的终端命令,后面的文件就是我们指定的mjs文件,当然这个文件你可以自己封装,只要是一个入口文件就可以,vue-cli源码这里指向的就是一个bin文件

发布该命令

npm link  // 将bin脚本下的命令进行发布到本地,本地就可以使用bin脚本中的命令

效果

wlm
function is success

注意事项

需要被执行的文件需要使用#!/usr/bin/env node 进行声明 否则是不生效的,该命令是映射到全局的,所以你在任何地方都是可以直接进行使用该命令的,就和你使用vue-cli是一样的效果

移除link

npm unlink  // 注意这里必须在项目文件中执行,不可以全局执行 

实现过程

脚本命令参数设计

wlm --help 查看使用帮助
wlm -V |--version 查看工具版本号
wlm list  列出所有可用模板
wlm inti <template-name> <project-name> 基于制定模板进行项目初始化 <> 代表的是必填项

下面的操作都是服务于上面👆这段参数设计,首先是我们已经将wlm的命令执行到本地,npm link已经完成了我们需要的第一步,后面就是这么在我们输入wlm之后的命令进行操作,首先我们需要将wlm后面输入的操作捕捉到,其实node提供给我们了原始的操作方式,比如下面

log(process.argv) // 我全局声明了 const log = console.log;  所以这里直接使用了log
输入:wlm iii
leimingwei@leimingweideMBP vue-cli-xa % wlm iii
[
  '/Users/leimingwei/.nvm/versions/node/v16.13.2/bin/node',
  '/Users/leimingwei/.nvm/versions/node/v16.13.2/bin/xa',
  'iii'
]
error: unknown command 'iii'
(Did you mean init?)

可以看到当我们输入命令之后,node自带的process.argv 是可以将我们输入的参数捕捉到的,但是这种写法我们是很难将用户的所有操作进行处理的,所以我们需要一个工具类来代替我们做这件事,那么这个工具就是commander

执行用户输入的命令行操作

yarn add commander // 安装commander工具
import { Command } from 'commander'; //进行命令行的操作
const program = new Command();
  • commanderGithub地址
使用
program
  .command('use') // 此处就是定义用户的输入
  .description('如何使用该cli') // 当用户输入-h 的时候提示的描述信息
  // 接受到用户输入的命令之后进行的操作
  .action(()=>{
    log(logSymbols.info, chalk.yellow('第一步:运行 wlm list'))
    log(logSymbols.info, chalk.yellow('第二步:运行 wlm init 模板名称 自定义名称'))
    log(logSymbols.info, chalk.yellow('第三步:按照步骤初始化模板即可'))
  })
  program.parse();
效果展示:
leimingwei@leimingweideMBP lm-cli % wlm use 
ℹ 第一步:运行 wlm list
ℹ 第二步:运行 wlm init 模板名称 自定义名称
ℹ 第三步:按照步骤初始化模板即可

有了上述工具之后我们可以做的事情就比较多了,首先可以自定义指令,之后可以根据自定义指令进行action的操作,action中有回调参数,可以获取到当前用户的操作结果,具体的使用说明可以看🔝上方提供的github链接中的说明文档,这里不做赘述

说明

该功能插件提供很多命令操作和很多选项操作,可以自己进行定义一些功能操作,比如获取到用户输入的命令进行下载或者执行一些动作都是可以的

下载用户想要的文件

用户的命令我们已经获取到了,这个时候我们需要进行根据用户的要求下载对应的仓库才可以,这里我们没办法直接使用git clone 下载,所以我们需要使用第三方的下载工具,download-git-repo 该工具可以帮助我们直接下载我们提供好的git下载地址

  • download-git-repo
git-repo基本使用
yarn add downlaod-git-repo
import download from 'download-git-repo'; 
const downloadUrl  = '地址' 
// PN || TN 是我的入参 你们可以直接写死自己需要的项目名字
download(downloadUrl, PN || TN, { clone: true }, (err) => {
  const spinner = ora('模板获取中...').start(); // ora后面会说到 一个加载动画
        if (err) {
          spinner.color = 'red';
          spinner.text = `模板获取失败,请重新操作,失败原因:${err}`;
          spinner.fail()
          return
        }
        spinner.color = 'green';
        spinner.text = '模板下载成功';
        spinner.succeed()
      })
限制用户输入操作和选择的脚本

当我们可以知道了用户输入的命令了 ,那么之后我们要做的就是这么可以让用户有选择和询问的效果,比如:是否安装路由?是否安装pinia等等操作,还有一些是给用户选择,比如你是安装vue2还是vue3等,这个功能需要我们使用另一个工具进行实现,inquirer工具

  • inquirer-github
inquirer的基本使用
 inquirer
        .prompt([
          {
            type: 'input',
            name: 'name',
            message: "请输入项目名称"
          }, {
            type: 'input',
            name: 'description',
            message: "请输入项目简介"
          }, {
            type: 'input',
            name: 'author',
            message: "请输入作者"
          }
        ])
        .then((answers) => {
          log.log(answers)
        })
        .catch((error) => {
          if (error.isTtyError) {
            log(logSymbols.error, chalk.red(error)) // 这里的logSymbols 和 chalk 后面会说到 
          } else {
            log(logSymbols.error, chalk.yellow(error))
   }
});
重写package.json文件

当我们拿到了用户的输入,也将模板下载好了,也已经让用户自己输入了自定义的内容,那么下一步就是怎么将用户输入好的东西进行重新写入到我们下载好的项目中,当然不需要我们自己手写,需要我们引入第三方的工具handlebars 和 node内置的fs文件操作模块

  • handlebars
handlebars的基本使用
yarn add handlebars
import handlebars from 'handlebars' //模板引擎 
import fs from 'fs' //node 内置模块 不需要单独引入
重写json
    const packagePath = `${PN}/package.json` //PN 文件名字
    const packageContent = fs.readFileSync(packagePath, 'utf8')
    const packageFinalValue = handlebars.compile(packageContent)(PC)
    log(chalk.green(packageFinalValue))
    fs.writeFileSync(packagePath, packageFinalValue)
json配置

当然只是重写还是不够的,需要我们的package.json进行配置,

{
  "name": "{{name}}",
  "author": "{{author}}",
  "description": "{{description}}",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "license": "ISC",
  "bin": {
    "wlm": "index.js"
  },
  "{{dependencies}}": {
    "commander": "^9.4.1",
    "download-git-repo": "^3.0.2",
    "handlebars": "^4.7.7",
    "inquirer": "^9.1.4",
    "router" : "{{router}}",
    "pinia" : "{{pinia}}"
  },
  "{{devDependencies}}": {

  }
}

我们需要进行重写的地方需要使用胡须模板进行变量接收参数

美化操作

上面提到的ora\chalk\logSymbols都是用来美化用户操作的,这里可以简单的理解为操作的界面更加舒适!

import ora from 'ora' //添加loading效果
import chalk from 'chalk'; // 提示文字
import logSymbols from 'log-symbols'; //提示符号
具体使用
  • ora
  • chalk
  • logSymbols

具体美化怎么使用的这里不做太多的介绍了,各自的官网已经写的很明白了,开头我已经将源码地址提供出来, 觉得我的文档写的太乱的可以直接用我写的源码也可以,因为一段时间没有写了,所以写的有点乱,所以这次我也是破天荒的直接提供所有的源码给你们,目的是不挨骂!

如何发布

发布npm

源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML CSS 网页设计作业「动漫小站」

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…

Neon intrinsics 简明教程

文章目录前言SIMD & NEONNEON intrinsicsNEON intrinsics 学习资料寄存器向量数据类型NENO intrinsics 命名方式NEON Intrinsics 查询三种处理方式&#xff1a;Long/Wide/NarrowNENO intrinsics 手册Addition 向量加法Vector add: vadd{q}_type. Vr[i]:Va[i]Vb[i]Vector lo…

Python-Flask 模型介绍和配置(6)

Flask数据模型和连接数据库一、安装二、配置数据库连接、创建模型类三、使用命令创建数据库表四、以注册为例flask是基于MTV的结构&#xff0c;其中M指的就是模型&#xff0c;即数据模型&#xff0c;在项目中对应的是数据库。flask与数据库建立联系有很多方法&#xff0c;但一般…

《安富莱嵌入式周报》第292期:树莓派单片机100M双通道示波器开源,MDK5.38发布,万用表单芯片解决方案,8通道±25V模拟前端芯片,开源贴片拾取电机板

往期周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 更新视频教程&#xff1a; GUI综合实战视频教程第3期&#xff1a;GUIX Studio一条龙设计主界面&#xff0c;底栏和…

【计算机毕业设计】32.学生宿舍管理系统源码

一、系统截图&#xff08;需要演示视频可以私聊&#xff09; 摘 要 随着计算机技术的飞速发展及其在宿舍管理方面应用的普及&#xff0c;利用计算机实现对学生宿舍管理势在必行。经过实际的需求分析&#xff0c;本系统采用Eclipse作为开发工具&#xff0c;采用功能强大的MySQL…

计算狗携手成都超算中心和重庆大学,共同助力“碳中和”

为了积极稳妥推进碳达峰碳中和&#xff0c;加快成渝双城经济圈建设。成都计算狗牵手国家超算中心和重庆大学&#xff0c;开展了关于二氧化碳电催化还原反应的路径计算工作&#xff0c;积极推动川渝两地实现产学研合作和成果落地转化&#xff0c;深入推进能源革命。 电催化还原二…

APS生产排单软件模拟排程功能

APS生产排单软件通过预先设定好相关基本资料与约束规则&#xff0c;当订单、机台、工具、材料、上下班时间等任何影响生产计划的因素变化后&#xff0c;执行“一键式排程计算”&#xff0c;系统即可生成生产详细排程。 通过选择不同的排产方案&#xff0c;可以实现不同的排程效…

3.60 怎么对OrCAD的网络标号进行统一批量修改?OrCAD中怎么设置复制位号的增加机制?

笔者电子信息专业硕士毕业&#xff0c;获得过多次电子设计大赛、大学生智能车、数学建模国奖&#xff0c;现就职于南京某半导体芯片公司&#xff0c;从事硬件研发&#xff0c;电路设计研究。对于学电子的小伙伴&#xff0c;深知入门的不易&#xff0c;特开次博客交流分享经验&a…

CANoe-vTESTstudio之Test Diagram编辑器(入门介绍)

1. 什么是Test Diagram编辑器 Test Diagram编辑器和Test Table编辑器不同 Test Table编辑器可以在编辑区域直接添加测试元素Test Case/Test Sequence/Test Fixture/Test Group,在CANoe软件的Test Unit里生成测试用例 Test Diagram编辑器以图形的方式定义实际的测试顺序、设…

springcloud16:总结配置中心+消息中心总结篇

架构图 启动分布式配置中心服务端从github中获取配置文件客户端访问服务端获取配置文件 当github中更改配置文件时&#xff0c;服务端可以立刻更改&#xff0c;但是客户端需要重启才能获取到更改的配置文件&#xff0c;如何优化&#xff1f; 即可以通过运维人员去手动刷新客户…

爬虫到底难在哪里?

爬虫本质是采集数据&#xff0c;通俗的讲就是模拟人在App或者浏览器的操作步骤自动化获取数据&#xff0c;本身没有什么难度&#xff0c;伪造HTTP 请求就好。 但是有些公司会给你设置采集障碍&#xff0c;大公司还有专门的安全团队防采集。 你看搞安全的程序员或者黑客平均技术…

【设计模式】组合模式(Composite Pattern)

组合模式属于结构型模式&#xff0c;又可以叫做部分-整体模式&#xff0c;主要解决客户程序在具有整体和部分的层次结构中&#xff0c;处理一组相似对象比处理单一对象费时费力的问题。例如&#xff0c;一个图形&#xff0c;它可以是一个简单的圆形、方形或一条线&#xff08;部…

paddleocr检测模型训练记录

标注好数据集后 分为训练集、测试集 数据集格式需要与配置文件一致&#xff0c;为了方便&#xff0c;我直接使用以下格式。 PaddleOCR主目录下&#xff0c;自己新建文件夹&#xff1a;car_plate_images/images_det train、test、里面是图片 det_label_test、det_label_train、…

Python遥感开发之GDAL读写遥感影像

Python遥感开发之GDAL读写遥感影像1 读取tif信息方法一2 读取tif信息方法二3 自己封装读取tif的方法&#xff08;推荐&#xff09;4 对读取的tif数据进行简单运算5 写出tif影像(推荐)前言&#xff1a;主要介绍了使用GDAL读写遥感影像数据的操作&#xff0c;包括读取行、列、投影…

基于51单片机霍尔汽车自行车码表测速测里程显示proteus仿真原理图PCB

功能&#xff1a; 0.本系统采用STC89C52作为单片机 1.LCD1602液晶分三种显示模式 a)显示实时速度和本次里程 b)显示当前时间 c)显示报警速度和总里程 2.超过报警速度将声光报警 3.功能按键介绍 a显示状态下: 上’键——电机速度1 下’键——电机速度-1 设置’键——电机启动/暂…

四、【基础】组件实例三大核心属性之一 state

文章目录1、CODE2、Result2.1、初始化2.2、触发更新3、state简写理解&#xff1a; state是组件对象最重要的属性, 值是对象(可以包含多个key-value的组合)组件被称为"状态机", 通过更新组件的state来更新对应的页面显示(重新渲染组件) 注意&#xff1a; 组件中rende…

算法导论习题—摊还时间代价分析、栈实现队列、贪心算法近似比、集合覆盖问题

在执行的nnn个操作中&#xff0c;有至多⌈lgn⌉⌈lg n⌉⌈lgn⌉个操作的次序是222的幂&#xff0c;这些操作的次序&#xff08;即代价&#xff09;如下 1,2,4,8,⋅⋅⋅,2⌈lgn⌉1, 2, 4, 8, , 2 ⌈lg n⌉ 1,2,4,8,⋅⋅⋅,2⌈lgn⌉ nnn个操作的总代价为 T∑k0⌈lgn⌉2k(n−⌈…

Android App网络通信中利用okhttp实现下拉刷新和上拉加载实战(抓取文章信息 超详细 附源码)

需要源码和工具类请点赞关注收藏后评论区留言私信~~~ 一、实现下拉刷新和上拉加载功能 网络上的信息很多&#xff0c;往往无法依次拉下来&#xff0c;故而App引入了分页加载功能&#xff0c;最开始先展示第一页内容&#xff0c;等到用户拉到该页底部后再去加载下一页内容&…

网络安全面试、实习、校招经验打包分享

整理收集了近些年的资料 内几乎覆盖了各大公司&#xff0c;大厂小厂都有 很多培训机构都是收费提供 本公众号无任何套路全部免费 提供下载学习 为了防止失效&#xff0c;建议下载收藏起来 以后总会用得上&#xff01; 下面截取部分资料 腾讯-安全技术实习生 时长&am…

流媒体技术基础-摄像头接口与标准

一、摄像头接口概括 摄像头按接口分类如下 主板直接接的专用接口 SPI接口&#xff1a;串行传输、速度慢。常用用于MCU DVP接口&#xff1a;并口传输&#xff0c;速度较慢&#xff0c;传输的带宽低。 MIPI接口&#xff1a;手机平台标准接口&#xff0c;差分串口传输&#xff…