tdesign vue初始化組件源碼解析
前言
Tdesign-vue 是一由騰訊開源的 Vue.js 組件庫。我們知道,這些大型的組件庫業(yè)務覆蓋面很廣,基本都包含了很多組件,很多組件包含了一些通用性代碼,如果每開發(fā)一個組件,都去把這些通用性代碼復制出來,無疑是非常繁瑣的,那么作者在開發(fā)這些組件時是如何做的呢?
學習目標:
- 新增組件: npm run init [組件名]
- 刪除組件:npm run init [組件名] del
資源:
源碼地址:tdesign-vue/index.js
源碼
找到用于初始化組件的源碼,如圖:

腳本的入口
function init() {
const [component, isDeleted] = process.argv.slice(2);
if (!component) {
console.error('[組件名]必填 - Please enter new component name');
process.exit(1);
}
const indexPath = path.resolve(cwdPath, 'src/index.ts');
const toBeCreatedFiles = config.getToBeCreatedFiles(component);
if (isDeleted === 'del') {
deleteComponent(toBeCreatedFiles, component);
deleteComponentFromIndex(component, indexPath);
} else {
addComponent(toBeCreatedFiles, component);
insertComponentToIndex(component, indexPath);
}
}
函數(shù)接受兩個參數(shù): Component 和 isDelete。
component參數(shù)是要創(chuàng)建或刪除的組件的名稱isDelete參數(shù)是一個標志,指示是否應該創(chuàng)建或刪除該組件。
函數(shù)首先檢查是否提供了組件參數(shù)。如果未提供,則向控制臺輸出一條錯誤消息,函數(shù)退出。否則,函數(shù)將繼續(xù)執(zhí)行。
之后,該函數(shù)獲取需要創(chuàng)建或刪除的文件列表,以便添加或刪除組件。然后檢查 isDelete 參數(shù)的值,以確定是否應該創(chuàng)建或刪除組件。如果 isDelete 等于 del,則函數(shù)調用 deleteComponent 函數(shù)來刪除組件,然后調用 deleteComponentFromIndex 函數(shù)來從項目的索引文件中刪除組件。如果 isDelete 不等于 del,則函數(shù)調用 addComponent 函數(shù)創(chuàng)建組件,然后調用 insertComponentToIndex 函數(shù)將組件添加到項目的索引文件中。
創(chuàng)建目錄
function addComponent(toBeCreatedFiles, component) {
// At first, we need to create directories for components.
Object.keys(toBeCreatedFiles).forEach((dir) => {
const _d = path.resolve(cwdPath, dir);
fs.mkdir(_d, { recursive: true }, (err) => {
if (err) {
utils.log(err, 'error');
return;
}
console.log(`${_d} directory has been created successfully!`);
// Then, we create files for components.
const contents = toBeCreatedFiles[dir];
contents.files.forEach((item) => {
if (typeof item === 'object') {
if (item.template) {
outputFileWithTemplate(item, component, contents.desc, _d);
}
} else {
const _f = path.resolve(_d, item);
createFile(_f, '', contents.desc);
}
});
});
});
}
該函數(shù)接受兩個參數(shù): toBeCreatedFiles 和 component。
toBeCreatedFiles參數(shù)是一個對象,它包含為了添加組件而需要創(chuàng)建的目錄和文件的列表component參數(shù)是要創(chuàng)建的組件的名稱。
函數(shù)首先迭代 toBeCreatedFiles 對象的鍵,這些鍵表示需要創(chuàng)建的目錄。對于每個目錄,該函數(shù)使用 fs.mkdir 函數(shù)創(chuàng)建目錄。如果目錄已經(jīng)存在,則函數(shù)將錯誤消息記錄到控制臺。
創(chuàng)建目錄后,函數(shù)將遍歷需要為組件創(chuàng)建的文件列表。如果文件是包含模板屬性的對象,則函數(shù)調用 outputFileWithTemplate 函數(shù)以使用模板創(chuàng)建文件。如果文件不是具有模板屬性的對象,則函數(shù)調用 createFile 函數(shù)創(chuàng)建空文件。
內容寫入
function insertComponentToIndex(component, indexPath) {
const upper = getFirstLetterUpper(component);
// last import line pattern
const importPattern = /import.*?;(?=\n\n)/;
// components pattern
const cmpPattern = /(?<=const components = {\n)[.|\s|\S]*?(?=};\n)/g;
const importPath = getImportStr(upper, component);
const desc = '> insert component into index.ts';
let data = fs.readFileSync(indexPath).toString();
if (data.match(new RegExp(importPath))) {
utils.log(`there is already ${component} in /src/index.ts`, 'notice');
return;
}
// insert component at last import and component lines.
data = data.replace(importPattern, (a) => `${a}\n${importPath}`).replace(cmpPattern, (a) => `${a} ${upper},\n`);
fs.writeFile(indexPath, data, (err) => {
if (err) {
utils.log(err, 'error');
} else {
utils.log(`${desc}\n${component} has been inserted into /src/index.ts`, 'success');
}
});
}
這個函數(shù)接受兩個參數(shù): component 和 indexPath。
component參數(shù)是要插入的組件的名稱indexPath參數(shù)是項目索引文件的路徑。
該函數(shù)首先定義兩個正則表達式: importPattern 和 cmpPattern。
importPattern正則表達式用于匹配索引文件中的最后一個import語句cmpPattern正則表達式用于匹配索引文件中的組件列表。
接下來,函數(shù)使用 getImportStr 函數(shù),使用變量(組件名稱的大寫版本)為新組件生成導入語句。
然后,該函數(shù)使用 fs.readFileSync 函數(shù)讀取索引文件的內容,并在文件中搜索 importPattern 和 cmpPattern 正則表達式。如果文件中已經(jīng)存在新組件的 import 語句,則函數(shù)將消息記錄到控制臺并返回。否則,該函數(shù)將最后一個 import 語句替換為新 import 語句,并將組件列表替換為包含新組件的新組件列表。最后,函數(shù)使用 fs.writeFile 函數(shù)將修改后的索引文件內容寫回文件。
刪除目錄
function deleteComponent(toBeCreatedFiles, component) {
const snapShotFiles = getSnapshotFiles(component);
const files = Object.assign(toBeCreatedFiles, snapShotFiles);
Object.keys(files).forEach((dir) => {
const item = files[dir];
if (item.deleteFiles && item.deleteFiles.length) {
item.deleteFiles.forEach((f) => {
fs.existsSync(f) && fs.unlinkSync(f);
});
} else {
utils.deleteFolderRecursive(dir);
}
});
utils.log('All radio files have been removed.', 'success');
}
該函數(shù)接受兩個參數(shù): toBeCreatedFiles 和 Component。
- toBeCreatedFiles 參數(shù)是一個包含與組件關聯(lián)的目錄和文件列表的對象
- component參數(shù)是要刪除的組件的名稱。
該函數(shù)首先調用 getSnapshoFiles 函數(shù)以獲取與組件關聯(lián)的快照文件列表。然后,它使用 Object.sign 函數(shù)將該列表與 toBeCreatedFiles 對象合并。
接下來,函數(shù)迭代合并對象的鍵,這些鍵表示需要刪除的目錄和文件。對于每個鍵,該函數(shù)檢查是否設置了關聯(lián)值的 deleteFiles 屬性。如果是,函數(shù)將遍歷文件列表并使用 fs.unlinkSync 函數(shù)刪除它們。如果未設置 deleteFiles 屬性,該函數(shù)將調用 deleteFolderRecursive 函數(shù)以刪除整個目錄及其所有內容。
刪除導入語句
function deleteComponentFromIndex(component, indexPath) {
const upper = getFirstLetterUpper(component);
const importStr = `${getImportStr(upper, component)}\n`;
let data = fs.readFileSync(indexPath).toString();
data = data.replace(new RegExp(importStr), () => '').replace(new RegExp(` ${upper},\n`), '');
fs.writeFile(indexPath, data, (err) => {
if (err) {
utils.log(err, 'error');
} else {
utils.log(`${component} has been removed from /src/index.ts`, 'success');
}
});
}
該函數(shù)接受兩個參數(shù): component 和 indexPath。
- component參數(shù)是要刪除的組件的名稱
- indexPath 參數(shù)是項目索引文件的路徑。
該函數(shù)首先使用 getImportStr 函數(shù),使用變量(組件名稱的大寫版本)為組件生成 import 語句。然后,它使用 fs.readFileSync 函數(shù)讀取索引文件的內容,并在文件中搜索 import 語句和組件名。
如果找到 import 語句或組件名稱,函數(shù)將使用 String.place 函數(shù)將其替換為空字符串。最后,函數(shù)使用 fs.writeFile 函數(shù)將修改后的索引文件內容寫回文件。如果在此過程中發(fā)生錯誤,該函數(shù)將一條錯誤消息記錄到控制臺。否則,它將記錄一條成功消息,指示組件已從索引文件中刪除。
總結
通過本次章節(jié)的學習,學習到了動態(tài)修改文件內容以及根據(jù)模板生成組件文件的方式。
以上就是tdesign vue初始化組件源碼解析的詳細內容,更多關于tdesign vue初始化組件的資料請關注腳本之家其它相關文章!
相關文章
vue項目開發(fā)中setTimeout等定時器的管理問題
這篇文章主要介紹了vue項目開發(fā)中setTimeout等定時器的管理問題,需要的朋友可以參考下2018-09-09
vue數(shù)據(jù)傳遞--我有特殊的實現(xiàn)技巧
這篇文章主要介紹了vue數(shù)據(jù)傳遞一些特殊梳理技巧,需要的朋友可以參考下2018-03-03
element tree懶加載:load="loadNode"只觸發(fā)一次的解決方案
本文主要介紹了element tree懶加載:load="loadNode"只觸發(fā)一次的解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-08-08

