这是系列文章 [前端脚手架实现]]() 的第二篇,在上文[脚手架Yue-cli的实现01-commander模块](http://wendingding.com/2019/05/02/Gossip%20-%20%E8%84%9A%E6%89%8B%E6%9E%B6Yue-cli%E7%9A%84%E5%AE%9E%E7%8E%B001-commander%E6%A8%A1%E5%9D%97/)中,介绍了如何让`Yue-cli`在用户的终端中可用,并通过`commander 模块`提供了`help、version以及 create 等基本指令`,本文将介绍脚手架中`Yue-cli create xxx`命令来初始化项目时内部的处理过程和实现方案。
安装axios
模块,该模块用来发送网络请求获取模板和对应的版本列表,该模板用来初始化 Vue 项目。
安装ora
模块,该模块的主要作用是在终端中显示提示消息。
安装inquirer
询问者模块,该模块展示根据拉取的模板和版本号列表,并让用户选择。
先修改 main.js 文件中action
中的实现方式,这样的话当执行Yue-cli create xx
指令的时候会加载并执行对应文件中的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| const program = require("commander")
const actions = { create: { description: 'create project with Yue-cli', alias: 'c', examples: [ 'Yue-cli create <project-name>', ], }, config: { description: 'config info', alias: 'conf', examples: [ 'Yue-cli config get <k>', 'Yue-cli config set <k> <v>', ], }, '*': { description: 'command not found', alias: '', examples: [], }, };
Object.keys(actions).forEach((action) => { program .command(action) .alias(actions[action].alias) .description(actions[action].description) .action(() => { console.log(`执行 action->`, action); console.log(process.argv);
require(path.resolve(__dirname, action))(...process.argv.slice(3)); }); });
|
在项目的src
目录中新创建 create.js 文件,这样当执行Yue-cli create xxx
指令的时候会自动加载并执行create.js
文件中的代码,当执行config xxx
指令的时候会自动加载并执行config.js
文件中的代码。这里主要讨论当执行create
指令的时候,命令行工具的内部应该处理哪些任务,下面列出代码的主要处理过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
const axios = require('axios'); const ora = require('ora'); const fs = require('fs'); const inquirer = require('inquirer');
async function getRepositoryList() { const { data } = await axios.get("https://api.github.com/orgs/Yong-template/repos"); return data; }
const getTagList = async(repo) => { const {data} =await axios.get(`https://api.github.com/repos/Yong-template/${repo}/tags`); return data; };
const loading = (fn, message) => async(...args) => { const spinner = ora(message); spinner.start(); const result = await fn(...args); spinner.succeed(); return result; };
module.exports = async(projectName) => {
let repoList = await loading(getRepositoryList, "fetching template ...")();
const { repo } = await inquirer.prompt({ name: "repo", type: "list", message: "please choice a template to create project !", choices: repoList.map(item => item.name) })
let tagList = await loading(getTagList, "fetching tags ...")(repo);
const { tag } = await inquirer.prompt({ name: 'tag', type: 'list', message: 'please choices tags to create project', choices: tagList.map(item => item.name), });
console.log("repo->",repo,"tag->",tag); };
|
列出简单列出脚手架指令Yue-cli create app
的执行情况。
1 2 3 4 5 6 7 8 9 10 11
| wendingding$ Yue-cli create app 执行 action-> create [ '/usr/local/bin/node', '/usr/local/bin/Yue-cli', 'create', 'app' ] ✔ fetching template ... ? please choice a template to create project ! vue-simple-template ✔ fetching tags ... ? please choices tags to create project (Use arrow keys) ❯ v2.0.0
|