tdesign vue初始化组件源码解析
codeniu 人气:0前言
Tdesign-vue 是一由腾讯开源的 Vue.js 组件库。我们知道,这些大型的组件库业务覆盖面很广,基本都包含了很多组件,很多组件包含了一些通用性代码,如果每开发一个组件,都去把这些通用性代码复制出来,无疑是非常繁琐的,那么作者在开发这些组件时是如何做的呢?
学习目标:
- 新增组件: 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); } }
函数接受两个参数: Component 和 isDelete。
component
参数是要创建或删除的组件的名称isDelete
参数是一个标志,指示是否应该创建或删除该组件。
函数首先检查是否提供了组件参数。如果未提供,则向控制台输出一条错误消息,函数退出。否则,函数将继续执行。
之后,该函数获取需要创建或删除的文件列表,以便添加或删除组件。然后检查 isDelete 参数的值,以确定是否应该创建或删除组件。如果 isDelete
等于 del
,则函数调用 deleteComponent
函数来删除组件,然后调用 deleteComponentFromIndex
函数来从项目的索引文件中删除组件。如果 isDelete
不等于 del
,则函数调用 addComponent
函数创建组件,然后调用 insertComponentToIndex
函数将组件添加到项目的索引文件中。
创建目录
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); } }); }); }); }
该函数接受两个参数: toBeCreatedFiles
和 component
。
toBeCreatedFiles
参数是一个对象,它包含为了添加组件而需要创建的目录和文件的列表component
参数是要创建的组件的名称。
函数首先迭代 toBeCreatedFiles
对象的键,这些键表示需要创建的目录。对于每个目录,该函数使用 fs.mkdir
函数创建目录。如果目录已经存在,则函数将错误消息记录到控制台。
创建目录后,函数将遍历需要为组件创建的文件列表。如果文件是包含模板属性的对象,则函数调用 outputFileWithTemplate
函数以使用模板创建文件。如果文件不是具有模板属性的对象,则函数调用 createFile 函数创建空文件。
内容写入
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'); } }); }
这个函数接受两个参数: component
和 indexPath
。
component
参数是要插入的组件的名称indexPath
参数是项目索引文件的路径。
该函数首先定义两个正则表达式: importPattern
和 cmpPattern
。
importPattern
正则表达式用于匹配索引文件中的最后一个import
语句cmpPattern
正则表达式用于匹配索引文件中的组件列表。
接下来,函数使用 getImportStr
函数,使用变量(组件名称的大写版本)为新组件生成导入语句。
然后,该函数使用 fs.readFileSync
函数读取索引文件的内容,并在文件中搜索 importPattern
和 cmpPattern
正则表达式。如果文件中已经存在新组件的 import
语句,则函数将消息记录到控制台并返回。否则,该函数将最后一个 import
语句替换为新 import
语句,并将组件列表替换为包含新组件的新组件列表。最后,函数使用 fs.writeFile
函数将修改后的索引文件内容写回文件。
删除目录
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'); }
该函数接受两个参数: toBeCreatedFiles 和 Component。
- toBeCreatedFiles 参数是一个包含与组件关联的目录和文件列表的对象
- component参数是要删除的组件的名称。
该函数首先调用 getSnapshoFiles 函数以获取与组件关联的快照文件列表。然后,它使用 Object.sign 函数将该列表与 toBeCreatedFiles 对象合并。
接下来,函数迭代合并对象的键,这些键表示需要删除的目录和文件。对于每个键,该函数检查是否设置了关联值的 deleteFiles 属性。如果是,函数将遍历文件列表并使用 fs.unlinkSync 函数删除它们。如果未设置 deleteFiles 属性,该函数将调用 deleteFolderRecursive 函数以删除整个目录及其所有内容。
删除导入语句
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'); } }); }
该函数接受两个参数: component 和 indexPath。
- component参数是要删除的组件的名称
- indexPath 参数是项目索引文件的路径。
该函数首先使用 getImportStr 函数,使用变量(组件名称的大写版本)为组件生成 import 语句。然后,它使用 fs.readFileSync 函数读取索引文件的内容,并在文件中搜索 import 语句和组件名。
如果找到 import 语句或组件名称,函数将使用 String.place 函数将其替换为空字符串。最后,函数使用 fs.writeFile 函数将修改后的索引文件内容写回文件。如果在此过程中发生错误,该函数将一条错误消息记录到控制台。否则,它将记录一条成功消息,指示组件已从索引文件中删除。
总结
通过本次章节的学习,学习到了动态修改文件内容以及根据模板生成组件文件的方式。
加载全部内容