面試官:請簡述一下vue-cli命令行工具,你能本身手寫一個嗎?

還記得咱們在寫vue 項目的時候用腳手架vue-init的主要做用是根據指定模板生成項目原型嘛?那麼vue-init怎麼實現的呢? 其實就是在vue-cli package.json中增長下面的代碼vue

{
  "bin": {
    "vue": "bin/vue",
    "vue-init": "bin/vue-init",   //執行vue-init 的時候下載項目原型
    "vue-list": "bin/vue-list",
    "vue-build": "bin/vue-build"
  }
}

複製代碼

具體實現請看下面:node

本篇的主要內容是:實現能夠在命令行中,直接運行代碼(下面的名字能夠本身取)。git

xl-cli install (安裝)
複製代碼

在實現本身的命令行運行代碼前,你須要對命令行,npm(包管理器)的基本用法有些瞭解。 下面進入正題:es6

//建立一個 xl-cli文件夾 mkdir xl-cli
// cd xl-cli 
// npm init  初始化
複製代碼

完成上面幾個步驟以後 咱們能看到生成了一個xl-cli文件夾 文件中包含一個package.json文件。github

{
  "name": "xl-cli",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
複製代碼

咱們知道在npm run xxx的時候其實就是執行的package.json中的scripts,好比上面 你看看npm run test就會輸出Error: no test specified,咱們的代碼用的es6須要編譯成es5,先建立一個npm run compile,(test沒用,同時給test刪掉)vue-cli

{
  "name": "xl-cli",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "compile": "babel src -d dist"
  },
  "author": "",
  "license": "ISC"
}
複製代碼

咱們須要安裝babel 建立 (安裝babel-cli babel-env)npm

src 
    --main.js
複製代碼

這個時候咱們執行 npm run compile其實就是至關於在命令行中輸入了 babel src -d dist 而後咱們看到了生成了一個這樣的目錄:json

dist
    --main.js
複製代碼

咱們常常會有這樣的需求就是在更改src 裏面的內容的時候 同步更改dist裏面的內容,能夠這樣作:在package.json的scripts增長一個 watch命令:api

{
  "name": "xl-cli",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "compile": "babel src -d dist",
    "watch":"npm run compile -- --watch"
  },
  "author": "",
  "license": "ISC"
}
複製代碼

而後運行 npm run watch命令 就實現了同步更新了!bash

下面實現 xl-cli命令行

建立 ./bin/www目錄, 要實如今命令行中使用 相似vue-cli這樣的命令 須要在package.json中增長

"bin": {
    "xl-cli": "./bin/www"
  },
複製代碼

./bin/www中的內容:

#! /usr/bin/env node

require('../dist/main.js');
複製代碼

第一行 最後的node是表示node環境 前面參數寫死的,第二行表示執行的代碼 ,建立完成後執行npm link,至關於在本地添加環境變量。 至此,你已經能夠執行xl-cli命令了,其實就是執行了dist/main.js。

實現像其餘命令行中的xl-cli --help 先引入一個包 commander ,這個包能夠幫助咱們設置和解析命令參數。 src/main.js

//main.js
import program from 'commander';

import {VERSION} from './utils/constants';

program.command('install')                            //加命令 
        .description('install template')
        .alias('i')
        .action(() => {
            console.log('用戶install了')
        })

program.version(VERSION,'-v --version').parse(process.argv);  //加 option
複製代碼

咱們能夠看到在命令窗口輸入 xl-cli install 會打印出:

用戶install了
複製代碼

好了 到如今咱們就剩下執行下載模板任務了,這樣咱們新建一個install.js來執行下載任務

//install.js
import ora from 'ora';   //ora 一個命令行loading效果
import inquirer from 'inquirer'  //命令行交互
import downLoadGit from 'download-git-repo';  //github api用來下載github的模板

let install = async () => {
    // 下載模板 
    let loading = ora('fetching template......');
    let answer = await inquirer.prompt([
        {
            type: 'input',        //你能夠輸入你本身的名稱
            name: 'projectName',
            message:'項目名稱',
            default:'xlDemo'    //默認名
        }
    ]);
    // 項目名字
    let project = answer.projectName;
    loading.start();
    //我在github上面上傳了一個很是簡單的模板 xlei1123/xl-cli downLoadGit(src, dest)  從哪拉 拉到那  process.cwd()+'/'+project這是拉到了當前目錄下的你剛剛命名的文件中
    downLoadGit('xlei1123/xl-cli',process.cwd()+'/'+project,(err) => {  
        if(err) {
            console.log(err)
            return;
        }
        console.log(process.cwd()+'/'+project)
        loading.succeed();
    });
}
export default install;
複製代碼

這樣在上面的action中執行 install()就行了!

//main.js
import program from 'commander';
import {VERSION} from './utils/constants';

import install from './install'
program.command('install')                            //加命令 
        .description('install template')
        .alias('i')
        .action(() => {
            install()
        })

program.version(VERSION,'-v --version').parse(process.argv);  //加 option
複製代碼

這樣咱們就完成了本身cli了,能夠執行下面幾個簡單的命令看一下效果:

xl-cli --help
xl-cli -v
xl-cli install
複製代碼

一句話總結:咱們發佈了一個npm包 這個包的package.json中有bin能夠全局執行,判斷參數有install,就從github上面拉取模板。

固然這篇實現的是簡單的命令行工具主要是理解其中大體原理,確定會存在不少不足的地方,歡迎各位提出寶貴的意見或建議,也但願能幫助到你從中得到一些知識!

相關文章
相關標籤/搜索