系列文章:node
前面的章節中咱們已經可以獲取到命令行中輸入的參數, 也能經過 gayhub 開放 api 中獲取到項目模板信息, 這裏咱們開始把以前的功能連綴起來 ^_^ios
本節用到的工具較多, list 一哈:git
bin/learn.jses6
#!/usr/bin/env node
require('../');
複製代碼
仍然做爲項目的引導文件, 直接引入項目根目錄下的 index.jsgithub
index.jsajax
require('babel-register');
const babel = require('@babel/core');
const babelPresetLatestNode = require('babel-preset-latest-node');
babel.transform('code();', {
presets: [[babelPresetLatestNode, {
target: 'current',
}]],
});
require('babel-polyfill');
require('./src');
複製代碼
根目錄下的 index 做爲項目的入口文件, 它的職責主要是兼容 es6, 並導入項目主文件 src/index.js
npm
src/index.jsjson
// colors console.log 文本添加字體顏色, 美觀
import 'colors';
// 接收命令行參數, 提供基礎信息提示功能
import commander from 'commander';
// 內部模塊
import { existsSync } from 'fs';
import { resolve } from 'path';
import { version } from '../package.json';
commander.version(version)
.parse(process.argv);
// 獲取命令行中傳入的第一個參數
const [todo = ''] = commander.args;
// 判斷若是 command 目錄下是否存在用戶輸入的命令對應的文件
if (existsSync(resolve(__dirname, `command/${todo}.js`))) {
require(`./command/${todo}.js`);
} else {
console.log(
` 你輸入了未知指令, 小哥哥我已經受不了掛了... `.red,
);
process.exit(-1);
}
複製代碼
這個是項目的主文件, 也是整個程序的總控. 正如註釋, 執行命令前, 從這裏檢測咱們的命令目錄下是否已經存在了用戶請求的命令, 避免了用戶誤操做程序報錯的風險.axios
command/download.jsapi
// 命令管理
import commander from 'commander';
// 命令行交互工具
import inquirer from 'inquirer';
// 命令行中顯示加載中
import ora from 'ora';
import Git from '../tools/git';
class Download {
constructor() {
this.git = new Git();
this.commander = commander;
this.inquirer = inquirer;
this.getProList = ora('獲取項目列表...');
this.getTagList = ora('獲取項目版本...');
this.downLoad = ora('正在加速爲您下載代碼...');
}
run() {
this.commander
.command('download')
.description('從遠程下載代碼到本地...')
.action(() => { this.download(); });
this.commander.parse(process.argv);
}
async download() {
let getProListLoad;
let getTagListLoad;
let repos;
let version;
try {
getProListLoad = this.getProList.start();
repos = await this.git.getProjectList();
getProListLoad.succeed('獲取項目列表成功');
} catch (error) {
console.log(error);
getProListLoad.fail('獲取項目列表失敗...');
process.exit(-1);
}
if (repos.length === 0) {
console.log('\n能夠開發的項目數爲 0, 確定是配置錯啦~~\n'.red);
process.exit(-1);
}
const choices = repos.map(({ name }) => name);
const questions = [
{
type: 'list',
name: 'repo',
message: '請選擇你想要開發的項目類型',
choices,
},
];
const { repo } = await this.inquirer.prompt(questions);
// 獲取項目的版本, 這裏默認選擇肯定項目的最近一個版本
try {
getTagListLoad = this.getTagList.start();
[{ name: version }] = await this.git.getProjectVersions(repo);
getTagListLoad.succeed('獲取項目版本成功');
} catch (error) {
console.log(error);
getTagListLoad.fail('獲取項目版本失敗...');
process.exit(-1);
}
console.log(`您選擇的項目是${repo}, 即將下載版本${version}`);
}
}
const D = new Download();
D.run();
複製代碼
command 目錄下存放的是咱們整個項目中全部的命令文件, 不一樣的命令對應不一樣的文件, 體現了單一職責的設計. download 命令用到了咱們上一節中提到的兩個接口(即獲取項目列表和獲取版本號列表)有疑問的同窗請回頭參考系列文章第三步 ^_^.
tools/git.js
import request from './request';
import { orgName } from '../../config';
class Git {
constructor() {
this.orgName = orgName;
}
getProjectList() {
return request(`/orgs/${this.orgName}/repos`);
}
getProjectVersions(repo) {
return request(`/repos/${this.orgName}/${repo}/tags`);
}
getProjectUrl() {
}
downloadProject() {
}
}
export default Git;
複製代碼
此文件是 git 相關的操做的文件, 因爲腳手架的核心功能就是獲取項目的 github 地址, 並下載, 因此個人 Git 類規劃了以上幾個功能, 獲取項目列表 獲取項目版本號列表 獲取項目地址 下載項目
, 雖而後兩個功能在這一節還用不到, 我也先留下了代碼樁
tools/request.js
import axios from 'axios';
import { baseURL } from '../../config';
const instance = axios.create({
baseURL,
timeout: 1e4,
});
// Add a request interceptor
instance.interceptors.request.use(config => config,
error => Promise.reject(error));
// Add a response interceptor
instance.interceptors.response.use(response => response.data,
error => Promise.reject(error));
export default instance;
複製代碼
這個文件僅僅是對 axios 作了一層簡單的封裝, 封裝的手法我還不是掌握的很好, 若是有精通的小夥伴歡迎評論區賜教.
config/index.js
// github 接口基礎地址
export const baseURL = 'https://api.github.com';
// organization 名稱
export const orgName = 'learn-cli-organization';
複製代碼
做爲整個項目的配置文件, 承擔了保存項目運行過程當中須要的配置信息的功能.
介紹完幾個文件, 感到如釋重負. 若是有手懶的小夥伴, 能夠直接 github clone 本階段代碼按照第一步的方法配置便可
ps: git clone https://github.com/luoquanquan/learn-cli.git
ps: git checkout 0.0.1
ps: 完成後要執行 npm i
和 npm link
的喲 ^_^
終於到了驗證的環節. 小夥伴們, 本身寫完或者 git clone 完代碼之後能夠打開終端啦, 484 有點小小的雞凍 ^_^
輸入 learn download
出現上圖所示的項目名稱和版本號, 說明咱們已經經過代碼獲取 git 項目信息成功啦.
下集預告: 到如今, 咱們已經可以從 github 獲取到項目的名稱和版本號, 下一步會嘗試把項目 download 到本地用到了工具 download-git-repo, 熱愛動手的小夥伴已經能夠開始着手啦, 說不定下一步就是你來寫喲 😄
因爲 github 開放 api 訪問次數的限制(未受權每小時只有 60 次), 因此咱們不得不加上受權.其實就是申請一個 github 受權 token 寫到代碼裏. 申請 token 的步驟在這裏
最後貼上添加 token 之後的一次提交記錄
爲何要把 token 先改爲亂碼在反轉回來呢? 由於腳手架代碼要上傳到 github, 上傳時候若是你的代碼中存在 github token 明文的話, 該 token 就會被刪除. (不說了都是淚....)
最終的代碼