本文参加了由公众号@若川视野 发起的每周源码共读活动, 点击了解详情一起参与。 这是源码共读的第34期 。
1. 简单介绍 TDesign 适配桌面端的组件库,适合在 vue 2 技术栈项目中使用 官网地址 Vue for Web | TDesign (tencent.com) git仓库: github.com/Tencent/tde…
2.安装及基础使用
npm i tdesign-vue
推荐使用 Webpack 或 Rollup 等支持 tree-shaking 特性的构建工具,无需额外配置即可实现组件按需引入:
import Vue from 'vue';
import TDesign from 'tdesign-vue';
// 引入组件库全局样式资源
import 'tdesign-vue/es/style/index.css';
Vue.use(TDesign);
3.初始化组件的命令
- 新增组件: npm run init [组件名]
- 删除组件:npm run init [组件名] del
- init代码结构
4. 入口文件 index
//从命令行获取参数
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);
}
}
init();
5.新增组件
// 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);
}
});
});
});
}
- 导入文件到index.ts中
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');
}
});
}
6.删除组件
const snapShotFiles = getSnapshotFiles(component);
const files = Object.assign(toBeCreatedFiles, snapShotFiles);
Object.keys(files).forEach((dir) => {
//dir为文件路径,如src/aaa
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');
}
//删除文件的时候需要检查下是否存在
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach((file) => {
const current = `${path}/${file}`;
if (fs.statSync(current).isDirectory()) {
deleteFolderRecursive(current);
} else {
fs.unlinkSync(current);
}
});
fs.rmdirSync(path);
}
}
- 然后删除在index.ts中的模块引入
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');
}
});
}
遇到的问题
用vscode debugger的时候,process.cwd()获取到的路径是'c:\mycode', 实际代码的路径是C:\mycode\tdesign-vue\tdesign-vue。 尝试使用了__dirname(这个路径是C:\mycode\tdesign-vue\tdesign-vue\script\init,执行的js的上层文件)。
总结:
学到的node文件系统api
fs.existsSync(path) 判断文件是否存在
fs.unlinkSync 同步取消链接 Returns undefined.
fs.writeFile(file, data[, options], callback)当文件是文件名时,异步将数据写入文件,如果文件已经存在则替换文件。 数据可以是字符串或缓冲区。
fs.mkdir(path[, options], callback) 异步创建目录
fs.readFileSync(tplPath) 同步读取文件内容