前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现一个自定义的vue脚手架

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

作者头像
何处锦绣不灰堆
发布2022-11-30 15:59:46
7650
发布2022-11-30 15:59:46
举报
文章被收录于专栏:农历七月廿一
开发背景

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

先看效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
实现过程中可能存在的问题
  • 如何获取用户的输入
  • 如果根据用户的输入进行相应的操作
  • 如何自定一个packag.json文件
  • 如何发布到npm
初始化一个package.json
代码语言:javascript
复制
npm init 或者 npm init -y
初始化一个测试文件
代码语言:javascript
复制
#!/usr/bin/env node
console.log("function is success")

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

运行该文件
代码语言:javascript
复制
node index.js
将node index.js 替换为自定义命令
比如:wlm

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

配置package.json
代码语言:javascript
复制
{
  "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文件

发布该命令
代码语言:javascript
复制
npm link  // 将bin脚本下的命令进行发布到本地,本地就可以使用bin脚本中的命令
效果
代码语言:javascript
复制
wlm
function is success
注意事项

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

移除link
代码语言:javascript
复制
npm unlink  // 注意这里必须在项目文件中执行,不可以全局执行 

实现过程

脚本命令参数设计
代码语言:javascript
复制
wlm --help 查看使用帮助
wlm -V |--version 查看工具版本号
wlm list  列出所有可用模板
wlm inti <template-name> <project-name> 基于制定模板进行项目初始化 <> 代表的是必填项

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

代码语言:javascript
复制
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

执行用户输入的命令行操作
代码语言:javascript
复制
yarn add commander // 安装commander工具
import { Command } from 'commander'; //进行命令行的操作
const program = new Command();
使用
代码语言:javascript
复制
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();
效果展示:
代码语言:javascript
复制
leimingwei@leimingweideMBP lm-cli % wlm use 
ℹ 第一步:运行 wlm list
ℹ 第二步:运行 wlm init 模板名称 自定义名称
ℹ 第三步:按照步骤初始化模板即可

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

说明

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

下载用户想要的文件

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

git-repo基本使用
代码语言:javascript
复制
yarn add downlaod-git-repo
import download from 'download-git-repo'; 
代码语言:javascript
复制
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的基本使用
代码语言:javascript
复制
 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的基本使用
代码语言:javascript
复制
yarn add handlebars
import handlebars from 'handlebars' //模板引擎 
import fs from 'fs' //node 内置模块 不需要单独引入
重写json
代码语言:javascript
复制
    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进行配置,

代码语言:javascript
复制
{
  "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都是用来美化用户操作的,这里可以简单的理解为操作的界面更加舒适!

代码语言:javascript
复制
import ora from 'ora' //添加loading效果
import chalk from 'chalk'; // 提示文字
import logSymbols from 'log-symbols'; //提示符号
具体使用

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

如何发布

发布npm

源码

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 开发背景
    • 先看效果:
      • 实现过程中可能存在的问题
      • 初始化一个package.json
      • 初始化一个测试文件
      • 运行该文件
      • 将node index.js 替换为自定义命令
        • 比如:wlm
        • 配置package.json
        • 发布该命令
        • 效果
        • 注意事项
        • 移除link
        • 实现过程
          • 脚本命令参数设计
            • 执行用户输入的命令行操作
              • 效果展示:
          • 源码
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档