仿vue-cli搭建属于自己的脚手架的方法步骤

脚手架是啥

从前我总觉得脚手架是个很高大上的东西,好像得牛叉:ox:一点的人才写的出来,可望而不可即。其实并不是因为困难使我们放弃,而是因为放弃才显得困难(这是个好词好句:see_no_evil:)。只要你肯花个一天半天的时间:fist:,也能写出属于你自己的脚手架。

早前脚手架这个词是从 vue-cli 这里认识的,我们通过 npm install -g vue-cli 命令全局安装脚手架后, 再执行 vue init webpack project-name 就能初始化好一个自己的项目,真是尼玛的神奇:hushed:。但你有没有想过为什么我们执行 vue init 这个命令就能有个自己的项目呢。今天,就让我们一起来揭开庐山真面目吧!

等等:hand:,扯了一堆,你好像还没说下啥是脚手架?emmm... 它就是个工具,方便我们新建项目用的,有了这个项目我们就能直接开发了。其实我们本可以用 git clone url 来新建(复制)项目,再 cuo 一点的方法就是复制粘贴整个文件夹,一样也能达到初始化的目的。脚手架的本质也是从远程下载一个模板来进行一个新项目。额。所以。。。有什么不同呢?就高大上啊:anguished:。当然不止于此啦,脚手架可是高级版的克隆,它主要是提供了交互式的命令让我们可以动态的更改模板,然后用一句命令就可以一劳永逸了(当然还是要维护的),这应该是最主要的区别吧,反正现在我是这么想的:cry:。

好了,本章的目的就是带领大家写一个简易版的脚手架 xr-cli(名字爱取啥取啥),目标是实现一个 xr init template-name project-name 这样的命令,废话少说,开始进入正题吧:rocket::rocket::rocket:。

源码地址: https://github.com/lgq627628/xr-cli

前置知识

其实一个简易版的 xr-cli 的代码量并不多,所以这里我们先来小小介绍一下其中要依赖的包,如果你用过这些工具可以跳过,没用过的请务必一定要瞟一眼。

commander

这是用来编写指令和处理命令行的,具体用法如下:

const program = require("commander");
// 定义指令
program
 .version('0.0.1')
 .command('init', 'Generate a new project from a template')
 .action(() => {
 // 回调函数
 })
// 解析命令行参数
program.parse(process.argv);

回忆一下,我们曾用过的 vue init 的命令就是这样声明的。

inquirer

这是个强大的交互式命令行工具,具体用法如下:

const inquirer = require('inquirer');
inquirer
 .prompt([
 // 一些交互式的问题
 ])
 .then(answers => {
 // 回调函数,answers 就是用户输入的内容,是个对象
 });

想象一下我们用 vue init webpack project-name 之后是不是会有几个交互问题,问你文件名啊、作者啊、描述啊、要不要用 eslint 啊等等之类的,就是用这个来写的。

chalk

这是用来修改控制台输出内容样式的,比如颜色啊,具体用法如下:

const chalk = require('chalk');
console.log(chalk.green('success'));
console.log(chalk.red('error'));

ora

这是一个好看的加载,就是你下载的时候会有个转圈圈的那种效果,用法如下:

const ora = require('ora')
let spinner = ora('downloading template ...')
spinner.start()

download-git-repo

看名字很明显了,这是用来下载远程模板的,支持 GitHub、 GitLab 和 Bitbucket 等,用法如下:

const download = require('download-git-repo')
download(repository, destination, options, callback)

其中 repository 是远程仓库地址;destination 是存放下载的文件路径,也可以直接写文件名,默认就是当前目录;options 是一些选项,比如 { clone:boolean } 表示用 http download 还是 git clone 的形式下载。

目录搭建

ok,有了上面的知识储备之后,我们就正式开始撸了。

首先我们要创建一个文件夹,并取名叫 xr-cli;

在该目录下执行 npm init 命令(你应该有安装 node 吧:joy:),一路回车,就会生成一个生成 package.json 文件,在 package.json 里面写入以下依赖并执行 npm install 安装,如下:

"dependencies": {
 "chalk": "^2.4.2",
 "commander": "^2.19.0",
 "download-git-repo": "^1.1.0",
 "inquirer": "^6.2.2",
 "ora": "^3.2.0"
}

新建一个 bin 文件夹,并在 bin 目录下新建一个无后缀名的 xr 文件,并写上:

#!/usr/bin/env node
console.log('hello');

这个文件就是我们整个脚手架的入口文件,我们用 node ./bin/xr 运行一下,就能在控制台打印出 hello,如下图:

这里要注意开头的 #!/usr/bin/env node

这个语句必须加上,主要是为了让系统看到这一行的时候,会沿着该路径去查找 node 并执行,主要是为了兼容 Mac ,确保可执行。

bin 目录初始化

当前,bin 目录下就只有一个文件,就是入口文件 xr。所以现在我们先来编写这个文件,由于内容较少,我们直接看代码:

#!/usr/bin/env node
const program = require('commander')

// 定义当前版本
// 定义使用方法
// 定义四个指令
program
 .version(require('../package').version)
 .usage('<command> [options]')
 .command('add', 'add a new template')
 .command('delete', 'delete a template')
 .command('list', 'list all the templates')
 .command('init', 'generate a new project from a template')

// 解析命令行参数
program.parse(process.argv)

这个文件的主要作用就是定义指令,现在我们用 node ./bin/xr 运行一下,就能看到如下结果:

当然,你可能会觉得每次输入 node ./bin/xr

这个命令有点麻烦,没关系,我们可以在 package.json 里面写入已下内容:

// bin 用来指定每个命令所对应的可执行文件的位置
"bin": {
 "xr": "bin/xr"
}

然后在根目录下执行 npm link (就是把命令挂载到全局的意思),这样我们每次只要输入 xr,就可以直接运行了,so cool,就像下面这样:

是不是好像有点样子了呢:grin::grin::grin:,那就让我们继续完善下 bin 目录吧!ok,让我们在 bin 目录下再新建四个文件,分别对应上面的四个指令,然后分别处理四个指令要做的事情,如下图:

同样的,我们修改一下 package.json 里面的 bin 内容,如下:

"bin": {
 "xr": "bin/xr",
 "xr-add": "bin/xr-add",
 "xr-delete": "bin/xr-delete",
 "xr-list": "bin/xr-list",
 "xr-init": "bin/xr-init"
}

然后执行 npm unlink 解绑全局命令,再执行 npm link 重新把命令绑定到全局,就像下面这样:

最后顺便在根目录下新建一个 template.json 文件,里面的内容就是一个 {}

编写具体指令

好了,一切准备就绪,接下来就让我们来写下具体的四个指令吧。

xr-add

这个内容也是比较少,直接看代码:

#!/usr/bin/env node

// 交互式命令行
const inquirer = require('inquirer')
// 修改控制台字符串的样式
const chalk = require('chalk')
// node 内置文件模块
const fs = require('fs')
// 读取根目录下的 template.json
const tplObj = require(`${__dirname}/../template`)

// 自定义交互式命令行的问题及简单的校验
let question = [
 {
 name: "name",
 type: 'input',
 message: "请输入模板名称",
 validate (val) {
  if (val === '') {
  return 'Name is required!'
  } else if (tplObj[val]) {
  return 'Template has already existed!'
  } else {
  return true
  }
 }
 },
 {
 name: "url",
 type: 'input',
 message: "请输入模板地址",
 validate (val) {
  if (val === '') return 'The url is required!'
  return true
 }
 }
]

inquirer
 .prompt(question).then(answers => {
 // answers 就是用户输入的内容,是个对象
 let { name, url } = answers;
 // 过滤 unicode 字符
 tplObj[name] = url.replace(/[\u0000-\u0019]/g, '')
 // 把模板信息写入 template.json 文件中
 fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
  if (err) console.log(err)
  console.log('\n')
  console.log(chalk.green('Added successfully!\n'))
  console.log(chalk.grey('The latest template list is: \n'))
  console.log(tplObj)
  console.log('\n')
 })
 })

这个文件主要目的就是添加模板并存储起来,上面的注释应该都写的挺清楚了。我们执行 xr add 来看看效果:

这里的模板名称(自己随便取)相当于 vue init webpack project-name 当中的 webpack

;模板地址要注意一下,像下面这样写就可以,这里以 github 为例:

xr-delete

如果你理解了上面的那个步骤,这步对你来说应该也是洒洒水啦!上代码:

#!/usr/bin/env node

const inquirer = require('inquirer')
const chalk = require('chalk')
const fs = require('fs')
const tplObj = require(`${__dirname}/../template`)

let question = [
 {
 name: "name",
 message: "请输入要删除的模板名称",
 validate (val) {
  if (val === '') {
  return 'Name is required!'
  } else if (!tplObj[val]) {
  return 'Template does not exist!'
  } else {
  return true
  }
 }
 }
]

inquirer
 .prompt(question).then(answers => {
 let { name } = answers;
 delete tplObj[name]
 // 更新 template.json 文件
 fs.writeFile(`${__dirname}/../template.json`, JSON.stringify(tplObj), 'utf-8', err => {
  if (err) console.log(err)
  console.log('\n')
  console.log(chalk.green('Deleted successfully!\n'))
  console.log(chalk.grey('The latest template list is: \n'))
  console.log(tplObj)
  console.log('\n')
 })
 })

应该很好理解,就不过多解释了,我们直接执行 xr delete 看下效果:

xr-list

这个更简单了,两行代码搞定:

#!/usr/bin/env node

const tplObj = require(`${__dirname}/../template`)
console.log(tplObj)

是不是简单到爆:boom:。我们执行 xr list 看看效果:

因为刚才一添加一删除,所以目前没有模板,就输出 {}

xr-init

这应该是最主要(但不难)的一步了,毕竟我们写到现在还没有通过命令初始化过一个项目呢:sob:。所以这步的重点就是执行 download 方法,并传入相应参数,具体看代码:

#!/usr/bin/env node

const program = require('commander')
const chalk = require('chalk')
const ora = require('ora')
const download = require('download-git-repo')
const tplObj = require(`${__dirname}/../template`)

program
 .usage('<template-name> [project-name]')
program.parse(process.argv)
// 当没有输入参数的时候给个提示
if (program.args.length < 1) return program.help()

// 好比 vue init webpack project-name 的命令一样,第一个参数是 webpack,第二个参数是 project-name
let templateName = program.args[0]
let projectName = program.args[1]
// 小小校验一下参数
if (!tplObj[templateName]) {
 console.log(chalk.red('\n Template does not exit! \n '))
 return
}
if (!projectName) {
 console.log(chalk.red('\n Project should not be empty! \n '))
 return
}

url = tplObj[templateName]

console.log(chalk.white('\n Start generating... \n'))
// 出现加载图标
const spinner = ora("Downloading...");
spinner.start();
// 执行下载方法并传入参数
download (
 url,
 projectName,
 err => {
 if (err) {
  spinner.fail();
  console.log(chalk.red(`Generation failed. ${err}`))
  return
 }
 // 结束加载图标
 spinner.succeed();
 console.log(chalk.green('\n Generation completed!'))
 console.log('\n To get started')
 console.log(`\n cd ${projectName} \n`)
 }
)

ok,我们执行一下 xr init simple test ,记得先执行一下 xr add

现在我们就可以在左侧的目录中看到 test 项目了,如下图:

至此,一个小小的脚手架就做完了。:rose::rose::rose:此处应该有鲜花和掌声:clap::clap::clap:

发布到 npm

既然以上命令都执行成功了,那接下来我们就把它发布到 npm 上吧(写都写了,不能浪费:grimacing:)。

  • 删除 test 文件夹,它就本地测试用的,用完就抛弃它(当然做人不能这样)
  • 在根目录下新建 README.md 文件,随便写点使用说明,假装正经一下
  • 在根目录下新建 .npmignore 文件,并写入 /node_modules ,意思就是发布的时候忽略 node_modules 文件夹,
  • 去 npm 官网注册个账号(很简单的),同时搜索一下 xr-cli 这个名字,看看有没有人用,有的话就换一个罗

现在让我们回到项目根目录,执行 npm login 登入 npm 账号,再执行 npm publish 发布,就像下面这样:

没错,就是这样两个简单的命令,我们就发布成功啦,真是可喜可贺:beer::beer::beer:。大概过一分钟左右(反正挺快的),我们再去 npm 官网搜下 xr-cli,就可以看到自己的脚手架啦,哈哈哈哈,贼开心:+1::+1::+1:。

这里补充说明一点:根据规范,只有在发包的24小时内才允许撤销发布的包,所以为了不污染 npm 网站,如果只是测试的话就执行 npm unpublish --force 删除吧,毕竟我们都是有素质的人。

小试牛刀

别急,还没有结束:no_good:‍♀️。发都发出去了,怎么也得验证一波撒。嗯,说的有道理,无法反驳,那就赶紧验收吧!这里我们记得先用 npm unlink 解绑一下命令,不然会相互影响。下面我们打开终端,输入 npm i xr-cli -g 全局安装一下脚手架,然后执行 xr ,如果出现下图中的模样就说明已经安装成功了。

接下来进入到桌面,执行 xr init simple xr-test,不一会就可以在桌面上看到自己的项目啦。

:six::six::six:,大赞无疆,大。。赞。。。无疆!!!

结语

上面的操作只要你熟悉了几遍之后,再去看看vue-cli的源码结构,你就会有种拨开云雾见月明的感觉(它只是比我们这个脚手架完善很多很多很多而已:sob::sob::sob:)。

当然了,这只是渣渣版本。你可以往里面添加更多的东西,比如自动化构建和动态模板啊(其实动态模板是个大头),然后尝试写下更多更好的交互和功能,这样你就也能拥有一个属于自己的脚手架啦,心动不如行动,还等什么呢,不要998,只要有键盘,赶紧敲吧同志们,Let's go!:rainbow:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解如何使用vue-cli脚手架搭建Vue.js项目

    1. 前言 vue-cli 一个简单的构建Vue.js项目的命令行界面 整体过程: $ npm install -g vue-cli $ vue init webpack vue-admin $ cd vue-admin $ npm install $ npm run dev 后面分步说明. 2. 安装 前提条件,Node.js >=4.x版本,建议使用6.x版本.npm版本 > 3.x 全局安装vue-cli $ npm install -g vue-cli 3. 使用 $ vue init

  • vue.js之vue-cli脚手架的搭建详解

    相比于主流的angular和react前端框架,vue在近年来也变得非常火热.他吸取了前两者的优点,同时学习曲线也更加平缓.所以本魔王准备入坑了~~ 首先从vue的脚手架搭建开始吧. 这里不得不吐槽,window相对mac和linux确实在软件开发方面,非常不方便,代码打包,环境搭建等,简直爆炸~~..然而,嗯,本魔王就是在用win10,哎~ 嘛,废话不多说,今天的任务就是把脚手架搭好,虽然流程不麻烦,但是npm这个东东,真的可以一不小心就磨掉一下午的时间.这里无论用命令行工具,还是Git Ba

  • 使用vue-cli(vue脚手架)快速搭建项目的方法

    vue-cli 是一个官方发布 vue.js 项目脚手架,使用 vue-cli 可以快速创建 vue 项目.这篇文章将会从实操的角度,介绍整个搭建的过程. 1. 避坑前言 其实这次使用vue-cli的过程并不顺利,反复尝试几次都遇到以下这个报错: 创建vue-cli工程项目时的报错 在网上查了很多资料才发现原来是node版本过低的问题,虽然没有找到官方对这个"过低"问题的解释,但是根据国外网友的经验之谈,应该是至少使用node6,我将node4更新至node8之后确实没有报错了,顺利搭

  • vue-cli脚手架搭建的项目去除eslint验证的方法

    eslint验证,为我们提升我们的代码质量和良好的编码风格带来了非常大的帮助,但是由于其语法验证的严格,很多程序员在初期使用的时候很不适应,就想怎么能够去掉eslint验证. 其实把eslint验证去除的方法并不复杂,因为我们的脚手架是基于webpack的,那么一般的配置操作都会在webpack工具的配置文件中进行配置,那么我们就直接找webpack的配置文件就可以了.可能我们的很多刚开始接触vue-cli脚手架工具的朋友可能会说我搭建完项目后,build目录下有3个webpack开头的配置文件

  • 使用vue-cli脚手架工具搭建vue-webpack项目

    最近更新了webpack配置详解,可移步vue-cli webpack详解 对于Vue.js来说,如果你想要快速开始,那么只需要在你的html中引入一个<script>标签,加上CDN的地址即可.但是,这并不算是一个完整的vue实际应用.在实际应用中,我们必须要一系列的工具,包括:模块化,转译,预处理,热加载,静态检测和自动化测试等.对于一个需要长期维护和大型的项目而言,这些工具是必不可少的,但是尝试配置初始化这些很痛苦.这就是我们发布vue官方提供的脚手架工具的原因,一个简单的构建工具,通过

  • vue-cli3.0 脚手架搭建项目的过程详解

    1.安装vue-cli 3.0 npm install -g @vue/cli # or yarn global add @vue/cli 安装成功后查看版本:vue -V(大写的V) 2.命令变化 vue create --help 用法:create [options] <app-name> 创建一个由 `vue-cli-service` 提供支持的新项目 选项: -p, --preset <presetName>       忽略提示符并使用已保存的或远程的预设选项   -d

  • 仿vue-cli搭建属于自己的脚手架的方法步骤

    脚手架是啥 从前我总觉得脚手架是个很高大上的东西,好像得牛叉:ox:一点的人才写的出来,可望而不可即.其实并不是因为困难使我们放弃,而是因为放弃才显得困难(这是个好词好句:see_no_evil:).只要你肯花个一天半天的时间:fist:,也能写出属于你自己的脚手架. 早前脚手架这个词是从 vue-cli 这里认识的,我们通过 npm install -g vue-cli 命令全局安装脚手架后, 再执行 vue init webpack project-name 就能初始化好一个自己的项目,真是

  • Vue项目打包部署到apache服务器的方法步骤

    vue项目在开发环境下,让项目运行起来,是通过npm run dev命令,原理是在本地搭建了一个express服务器. 但是在服务器上就不是这样的,必须要通npm run build命令来对整个项目进行打包,打包后会在项目目录下生成一个dist文件夹,内容如下: 然后就是把这些文件丢到服务器上的某个文件夹下,我这里的文件夹名字是ibms 遇到的问题: 1. 直接去访问http://www.xxx.com/ibms/,会发现网页是白屏的,什么都没有,这就比较奇怪了,其实是因为资源加载的路径有问题!

  • Linux搭建C++开发调试环境的方法步骤

    安装g++ Linux编译C++程序必须安装g++编译器.这里使用yum方式安装.首先切换到root账号,su - root 然后输入密码. 执行yum install gcc-c++(注意不是yum install g++),报错. 报错是因为yum需要配置正确的服务器地址,服务器是提供yum安装包的,也被称作yum源.配置yum源的配置文件在/etc/yum.repos.d/目录下,可以看到系统自带了两个文件. cat 文件名称,会打印文件全部内容.可以看到两个文件要么没配置,要么地址是无法

  • 手把手搭建Java共享网盘的方法步骤

    项目介绍 在线共享网盘采用jsp+servlet搭建项目结构实现共享网盘,项目分为管理员,普通用户和付费用户三种角色,根据不同角色控制不同权限,实现不同用户对个人文件文件,所有文件,共享文件的增删改查操作. 项目适用人群 正在做毕设的学生,或者需要项目实战练习的Java学习者 开发环境: jdk 8 intellij idea tomcat 8.5.40 mysql 5.7 所用技术: jsp+servlet js+ajax layUi jdbc直连 项目访问地址 http://localhos

  • 从0到1搭建Element的后台框架的方法步骤

    由于最近公司要开发一个后台管理系统,查阅了很多vue框架,本人觉得element简洁,方便,于是选择它作为我们的首选框架,并分享给大家,如果您觉得有需要改进的地方可以提出来一起探讨,Github地址.本文篇幅比较长,希望同学们可以耐心的读下去,如有不懂可以下方留言 一.初始化项目 首先全局安装的vue框架,这里是用的npm包管理工具来安装的,如果你的网不是很好的话可以先安装淘宝镜像 npm install -g cnpm -registry=https://registry.npm.taobao

  • 搭建一个nodejs脚手架的方法步骤

    1 前言 1.1 像我们熟悉的 vue-cli,taro-cli 等脚手架,只需要输入简单的命令 taro init project ,即可快速帮我们生成一个初始项目.在日常开发中,有一个脚手架工具可以用来提高工作效率. 1.2 为什么需要脚手架 减少重复性的工作,从零创建一个项目和文件. 根据交互动态生成项目结构和配置文件等. 多人协作更为方便,不需要把文件传来传去. 1.3 怎样来搭建呢? 脚手架是怎么样进行构建的呢,我是借助了 taro-cli的思路. 1.4 本文的目标读者 1 想要学习

  • 搭建一个Koa后端项目脚手架的方法步骤

    一.背景 结合当前的node比较火的三大框架,Express.Koa.egg.笔者之前用的Express,后面发现回调把我搞死了,实在太无奈了.终于有一天去尝试了Koa来进行开发,发现实在太舒服了.ES6语法支持很多,同步模式也很到位,但是在学习koa的过程中,发现基本的基础知识都了解了,也按照官方的文档走了一遍,但发现好像无从下手.感觉开发过程中,分层不太明显,业务逻辑简单还好,一多麻烦就来了.查看了资料后,有一个koa的脚手架叫做 koa-generator ,马上尝试后发现不是我想要的模板

  • 基于webpack4.X从零搭建React脚手架的方法步骤

    项目初始化 $ npm init 安装webpack 本次创建是基于webpack4 $ npm install --save-dev 新建webpack配置文件 在根目录创建build文件夹,添加一个js文件,命名为webpack.base.conf.js // webpack.base.conf.js 文件 const path = require('path'); const DIST_PATH = path.resolve(__dirname, '../dist'); module.ex

  • 从零搭一个自用的前端脚手架的方法步骤

    为什么要弄个脚手架 对于我个人,经常写些demo,或者写一个新项目的时候,要么就是把以前的项目模板复制一份,要么就是重新搭建一份,显得比较麻烦,浪费时间,所以就有了搭建一个能满足自己需要的脚手架. 脚手架的效果 这是一个基本的脚手架,init一个项目,输入项目名称,版本号等信息,然后从git仓库拷贝一份自己需要的项目模板.类似vue的vue-cli或者react的create-react-app,只是这个比较简单. 基本思路参考下图 这部分参考了掘金@张国钰大佬的思路. 项目结构 主要3个,一个

  • 用vue封装插件并发布到npm的方法步骤

    一.基于vue的国家区号列表 vue-flag-list包含了大部分国家的区号,点击右边的三角形展开列表可以选择国家区号,若列表中没有区号,也可以自己输入区号. 全球区号列表 1.1 初始化组件 用的是vue-cli来初始化组件,虽然有很多东西不需要,因为对这个比较熟悉,所以还是按照这个步骤来. vue init webpack vue-flag-list cd vue-flag-list cnpm install npm run dev 1.2 根据自己的需求,实现具体功能,我的主要功能写在v

随机推荐