乐趣区

根据vuecli手摸手实现一个自己的脚手架

故事背景

身为一个入门前端七个月的小菜鸡,在我入门前端的第一天就接触到了 vue,并且死皮赖脸的跟他打了这么久的交到,还记得第一次用 vue init webpack 这句命令一下生成一个模板的时候那种心情,当时我就想,要是自己也能写一个的话,那会是灰常吃鸡的吧 o(~▽~) ブ, 所以说今天我们也要简单实现一个自己的脚手架

认识 bin

bin 的作用

首先我们先来了解一下这个 bin,这个 bin 和我们最开始用的 vue init webpack 这个命令是息息相关的

还记得我们在最开始安装 vue-cli 的时候嘛

    npm install vue-cli -g
    
  • 这条命令的意思是把 vue-cli 安装到全局,以至于你再任何一个地方打开 cmd 的时候都能够使用 vue init webpack

vue init webpack 这条命令实际上是执行的 vue-cli 里边 package.json 里边的 bin 属性下的命令

这个文件大概位置如下

这个路径里边有隐藏的路径,在查找的时候记得打开隐藏目录可见

这个 bin 里边大概长成这个样子

由图中可见,这里边有三个命令

    vue vue-init  vue-list
  • 这个三个命令的意思是执行对应的文件,Npm 会在 node_modules/.bin/ 目录下建立符号链接。又因为 node_modules/.bin/ 目录会在运行时加入系统的 PATH 变量,因此在运行 npm 时,就可以不带路径,直接通过命令来调用这些文件。

bin 所执行的文件和参数

那么说到这里你肯定会好奇这个文件是怎么做到生成模板的对吧,那么我们就来看一下被执行的这个文件到底是何方神圣

    #!/usr/bin/env node

    const program = require('commander')
    
    program
      .version(require('../package').version)
      .usage('<command> [options]')
      .command('init', 'generate a new project from a template')
      .command('list', 'list available official templates')
      .command('build', 'prototype a new project')
      .command('create', '(for v3 warning only)')
    
    program.parse(process.argv)

上边这一坨代码就是 执行 vue init webpack 的文件所有内容

首先最重要的一点就是 第一句 #!/usr/bin/env node

这句代码不可以没有,#! 指明这个脚本文件的解释程序,然后这个 /usr/bin/env 是说在系统的 PATH 目录中查找

这句话整体的意思就是说会有一个新的 shell 执行指定的脚本,执行这个脚本的解释程序是 node
如果不加这句代码的话是会报错的

然后下边这个引入了一个 commander 包 这是一个很牛逼的大佬写的一个关于命令行一些操作的包,command 里边的是定义一些子命令,然后后边在跟的参数,这里暂且不深扒了,附上中文文档

commander 中文文档

写一个自定义命令

好,那么我们现在了解了 bin 的基本概念和大致流程,下面我们来写一个自己的命令

首先新建一个文件夹,在 package.json 里边加上这么一句代码

 "bin": {"zjs-cli": "main.js"},

和新建一个 main.js 的文件

然后莫慌,我们还需要再执行一个命令就是

npm link 

我们之前全局安装的都会默认在 npm 的 node_modules 目录下,这个命令可以简单的理解为在 npm 的 node_modules 创建了一个快捷方式

到此为止我们得自定义命令算是走通了,接下来我们说一说文件里边得内容

搭建脚手架

脚手架得工作流程

上边我们知道了 bin 得作用并且,把我们得自定义命令和文件关联了起来,那么脚手架具体是怎么操作的呢,大概步骤如下

  • 进入文件,根据指定的地址和编译器,执行我们的 js
  • 从命令行接受参数,执行对应的操作
  • 交互性的询问问题,根据配置选择拉取的模板
  • 从 git 拉取模板

我们之前用的 vue 的脚手架大概的流程就是这样的

安装依赖

在进入文件之后,为了能够得到命令行的操作我们就要安装一些依赖了比如说 commander 的这个包

    npm install commander 
    

然后命令行默认的字体颜色是黑白色的,我们可以引入一些命令行交互的包,不得不说这些写包的大佬是真牛逼,啥都能写

    npm install chalk

vue 有一个 init 子命令,那我们也叫 init 好了

    const cmd = require("commander");
    const chalk = require('chalk')

    cmd.command('init').description('初始化模板').action(async (args) => {//。。。})
    
    cmd.parse(process.argv) 
    
  • 其中 command 是添加子命令的
  • description 是描述
  • action 是执行这个命令的回调
  • parse 是解析你命令行里边传进来的参数 比如 你写了一个 zjs-cli init demo,那么这个时候 回调里边的 args 的值就是 demo 这个字符串

然后需要注意 process 上的是 argv,里边用的是 args,这里不是笔误,当时我刚开始玩的时候纳闷了好半天

然后做一些交互,让我们得脚手架看起来更顺溜一些

npm install inquirer

npm install ora

上边这两个分别是加载动画和回答问题得,比如 vue 在新建模板得时候问你的一些列问题,还有那个下载中等待得 loading 动画

不要问我怎么能记住这么多得包名字,因为我是看的 vue-cli 源码认识得。。。。

拉取 git

这里单独把拉取 git 拿出来说,虽所内容不多,但毕竟也是今天的主角 o(~▽~) ブ

那么问题来了,怎么下载模板呢?很简单,当然还是 npm 包。。。。

npm install download-git-repo

这个包是可以从 github 上边下载包的

比如说我之前写的一个 demo 他叫 zjs-template,那么拉取的路径就是我得 git 路径加项目名称

let url = 'zhou1591/zjs-template'

// 然后第二个参数是拉取下来后的名称

// 这里我选择用命令行里边传过来的参数做名字

let  name = 'args'

然后根据 api 拉取模板,关闭

let downGit = (name) => {
downLoad(url, name, {clone}, err => {process.exit(1)
    })
}

完整代码如下

// git 包
const downLoad = require('download-git-repo')
// 动画
const ora = require('ora')


let url = 'zhou1591/zjs-template'
let clone = false
let downGit = (name) => {const spinner = ora('正在拉取模板...')
    spinner.start()
    downLoad(url, name, {clone}, err => {spinner.stop()
        console.log(err?err:"项目创建成功")
        process.exit(1)
    })

}
module.exports = downGit

引到 main.js 里边跑起来就好了,到此为止一个简单的脚手架已经 ok 了,就差了最后一步

发布脚手架

创建 npm 账号并发布

我们写完了一个自己的脚手架之后,当然是想迫不及待的体验一番的

首先我们创建一个 npm 的账号 npm 官网

之后在我们刚才的项目里边

  • npm login 输入你的账号密码邮箱
  • 然后登陆成功后 npm publish 推送
  • package.json 里边的 name 是你的 npm 包发布的名称
  • keywords 是搜索你的包的关键字
  • description 是你的包描述
  • version 是你的版本号

第一次发布 npm 包可能会遇到的问题

这个是说已经有重复名字的包了 你没有权限去推

  • you must verify your email before publishing a new package: https://www.npmjs.com/email-edit : “your module name”

这个是说第一次发布的时候 说你需要验证邮箱,在你登陆的最上方

  • 每次发布的时候需要更改你的版本号
  • 还有一个比较重要的 npm ERR! no_perms Private mode enable, only admin can publish this module:

这个是说你没有在 npm 最开始的源上边,你可能切换比如淘宝等等其他的源,当时我就是因为用了公司的源,怎么登陆都登陆不上去,很蛋疼

完美撒花

好了,到这里我们的第一个脚手架就算是完事了,运行一下

// 全局安装一下
npm install zjs-template -g
// 按照之前的命令
zjs-cli init myDemo

我得 zjs-cli 的 git 地址 https://github.com/zhou1591/z…
我得 zjs-template 的 git 地址 https://github.com/zhou1591/z…

希望我们每一个前端都喜欢前端,都能够在学习中不断充实自己 o(~▽~) ブ

下一篇我会简单实现一个 vuex,喜欢的请点个赞吧~

退出移动版