『手撕Vue-CLI』拉取模板名稱

BNTang發表於2024-05-27

前言

好,經過上篇文章的介紹,已經可以有處理不同指令的能力了,接下來我們就來處理 vue create 指令,這個指令的本質就是從網路上下載提前準備好的模板,然後再自動安裝模板中相關依賴。

所以實現 create 指令分為兩步:

  1. 下載指定模板
  2. 安裝模板中的依賴

先來看看官方的吧,我在終端中已經輸入了 vue create 指令,然後按照提示輸入了專案名稱,然後就會出現下面的提示:

他這個版本好像比較新,我這裡就直接以 Vue.2x 為例,在之前的版本呢其實首先是會讓你選擇一個模板的,然後再根據模板拉取模板,所以我會按照這個思路去寫。

拉取模板名稱

拉取模板名稱的話,首先要面臨的一個問題是,這些模板名稱是從哪裡來的呢?這個問題其實很簡單,得要自己去 Git 倉庫中進行建立好模板,然後再去拉取,這裡我使用的是 GitHub 倉庫,所以我會在 GitHub 倉庫中好需要使用的模板,然後再去拉取。

模板分為兩種,一種是需要編譯的模板,一種是不需要編譯的模板。

在 GitHub 倉庫中建立模板

因為我這裡要使用到 GitHub Api,根據 Api 要求只有組織的倉庫才能使用,所以需要在我的賬號中建立一個組織,然後再在組織中建立倉庫。

首先登入 GitHub,進入:https://github.com/settings/organizations ,然後點選 New organization 建立一個組織:

選擇 Free,點選 Create a free organization

看下圖,根據我填寫的資訊,替換成你自己的資訊,然後點選 Next

跳過這一步,點選 Skip this step

到此,我們已經建立好了一個組織:

接下來就是在組織中建立一個倉庫了,點選 Create new repository

建立 vue-simple-template 倉庫

這個是一個不需要編譯的模板:

後續就是根據給出的指令進行操作將提前準備好的模板上傳到倉庫中即可。

最後附上 vue-simple-template 倉庫地址:https://github.com/neo-it6666/vue-simple-template

當然你也可以將這個模板展示到自己組織的 Overview 中,這樣別人就可以看到你的模板了。怎樣設定呢?首先進入到 vue-simple-template 倉庫中,然後點選 Edit Pins

最後效果如下:

好,這個就是不需要編譯的模板,接下來快速將下一個需要編譯的模板建立好。

建立 vue-advanced-template 倉庫

一樣的我這裡就快速創了:

貼一個 vue-advanced-template 倉庫地址:https://github.com/neo-it6666/vue-advanced-template

同樣的,你也可以將這個模板展示到自己組織的 Overview 中,這樣別人就可以看到你的模板了。

拉取 GitHub 倉庫中的模板名稱

接下來就是拉取模板名稱了,這個其實很簡單,只需要使用 GitHub Api 就可以了,所以先要給大家介紹一下 GitHub Api。

GitHub Api

GitHub Api 是一個 RESTful 風格的 Api,可以用於獲取 GitHub 上的資源,比如倉庫、使用者、組織等等。

GitHub Api 的請求地址是:https://api.github.com,然後後面跟上你要請求的資源路徑,比如獲取使用者資訊的話,請求地址就是:https://api.github.com/users/neo-it6666

我這裡要獲取的是組織中的倉庫,所以要去文件中找與 Repositories 相關的 Api,文件地址:https://docs.github.com/en

點選 Repositories,然後找到 Repositories 中的 List organization repositories

透過這麼一頓操作過後,找到了 GET /orgs/{org}/repos,這個 API 主要作用就是列出指定組織的儲存庫。

簡單解釋一下這個請求地址:

  • orgs:固定寫死的,表示組織
  • org:組織名稱,就是你建立的組織名稱
  • repos:這個也是固定寫死的,表示倉庫

我組織叫 neo-it6666,所以請求地址就是:https://api.github.com/orgs/neo-it6666/repos

先在瀏覽器中輸入這個地址,看看返回的資料:

總共有 2 個倉庫,這個就是我們之前建立的兩個倉庫,返回是一個陣列,陣列中的每一項就是一個倉庫的資訊,是一個物件。

展開一個倉庫的資訊(物件)進行檢視發現,裡面有一個 name 欄位,這個就是倉庫的名稱,所以我們只需要獲取這個欄位就可以了。

好,知道了這些資訊之後呢鋪墊就差不多了,接下來就是在我們的專案中去拉取模板名稱了。

拉取模板名稱

由於我們要拉取模板名稱,涉及到網路請求,所以我們需要安裝一個網路請求的庫,這裡我使用的是 axios,所以先安裝 axios

npm install axios

改寫 create.js 檔案,首先引入 axios

const axios = require("axios");

我這裡單獨抽取一個函式用於拉取模板名稱,取名為 fetchRepoList

const fetchRepoList = async () => {
    const res = await axios.get('https://api.github.com/orgs/neo-it6666/repos')
    return res;
}

然後在 module.exports 中呼叫這個函式:

module.exports = async (projectName) => {
    const fetchRepoListVar = await fetchRepoList()
    console.log(fetchRepoListVar);
}

然後在終端中輸入 vue create,然後輸入專案名稱,然後就會看到下面的輸出:

發現我需要的資料在 data 欄位中,所以請求的程式碼要改一下,我直接透過解構賦值的方式取出 data 欄位:

const fetchRepoList = async () => {
    const { data } = await axios.get('https://api.github.com/orgs/neo-it6666/repos')
    console.log(data);
    return data;
}

下一步就是拿到了這個資料之後,我們要將這個資料中的 name 欄位取出來,然後展示到終端中,這個就是我們要的模板名稱了。

module.exports = async (projectName) => {
    const fetchRepoListData = await fetchRepoList();
    const templateNames =  fetchRepoListData.map((item) => item.name);
    console.log(templateNames);
}

然後在終端中輸入 vue create,然後輸入專案名稱,然後就會看到下面的輸出:

到這已經完成了拉取模板名稱的功能,但是透過我觀察官方的輸出,他是有下載 loading 的,所以我也想加上這個功能,也就是控制檯的互動,讓使用者知道正在下載模板,告訴使用者我在幹事情我在幫你下載中。

新增下載 loading

這個東西其實就是一個動畫,我這裡直接使用 ora 這個庫,所以先安裝 ora

先來簡單給大家介紹一下 ora 這個庫,ora 是一個用於建立 loading 動畫的庫,可以用於在終端中展示一個 loading 動畫,讓使用者知道程式正在執行中。

官方文件:https://www.npmjs.com/package/ora

安裝 ora

npm install ora

改寫 create.js 檔案,引入 ora

const ora = require("ora");

然後在 fetchRepoList 函式中使用 ora

const fetchRepoList = async () => {
    const spinner = ora('Loading template list...').start();
    const { data } = await axios.get('https://api.github.com/orgs/neo-it6666/repos')
    spinner.succeed('Template list loaded successfully');
    return data;
}

我先執行一下看看效果,然後在解釋一下 ora 的使用:

發現報錯了,大致意思是最新版 ora 這個庫使用的是 ES6 模組,要使用 import,透過我一頓操作與查閱資料,最後採取降低版本的方式來解決該問題。

ora 的版本降低到 5.4.0:

npm install ora@5.4.0

然後再執行一下看看效果:

其實這裡我應該錄製一個動圖的,大家自己去編寫程式碼看看效果吧。

最後我總結一下,因為我 NodeJS 版本為 15.6.0 ,所以 ora 庫的版本要降低到 5.4.0,有可能你們的版本和我的不同遇到的場景也不同,所以要根據自己的情況來做出相應的調整。

透過解決此問題,我也學到了很多,這並不是解決問題的最佳方法,由於自己的能力有限,所以只能採取這種方式,在日後的學習自身的提升中,希望能夠找到更好的解決方案,並解釋出來。

參考資料

  • https://blog.csdn.net/lt012345/article/details/131273244

相關文章