背景
在 vue2.x 中使用 element 组件会有代码提示如下
哇哦!用起来真的好爽!
那么我自己的全局组件怎么做到呢?
- 它提供了实现这一因为的方案。
- 在 package.json 中定义 vetur 并引入 tags/attributes 两个 json 文件
奈斯!接下来就是如何批量的完成这一步骤了
现在就有有 jym 说你可以用 vue-docgen-api 写呀,啊对对对,但是我不听。 没有错以前我通过vue-docgen-api写过这么一篇文章,但是现在我不。我要自己用手写。(手动滑稽)
依赖安装
npm install fs-extra vue-template-compiler @babel/parser @babel/traverse
- fs-extra:文件操作
- vue-template-compiler:针对 sfc 文件进行分解
- @babel/parser:对代码解析得到 ast 树
- @babel/traverse:遍历 ast 树进行一些操作
我的构思
针对全局组件进行遍历获取组件名称和需要外部传入的 props,进行 ast 树的遍历最总组合成我需要的 tags/attributes 两个 json 文件
初始化代码
const path = require("path");
const fs = require("fs-extra");
const compiler = require("vue-template-compiler");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const tags = {};
const attributesJson = {};
// 初始化
const init = async function (src) {
// 获取根目录
const rootDir = path.resolve(src);
// 获取文件列表
const fileList = await fs.readdir(rootDir);
if (fileList.length) {
fileList.forEach(async (dirSrc) => {
const filePath = `${rootDir}\\${dirSrc}`;
const isDir = await fs.stat(filePath);
if (isDir.isDirectory()) {
// 递归遍历
recursiveGetSfc(filePath);
} else {
// 读取sfc文件
await readSfc(filePath);
}
});
}
};
const recursiveGetSfc = async function (src) {
await init(src);
};
- init:此方法主要是获取文件并对其进行判断是否是文件夹,是文件夹继续遍历获取文件直到拿到所有的组件文件为止
const readSfc = async function (src) {
const baseName = path.basename(src);
const tagsAttributes = [];
let attrName = null;
// 当为index.vue时做一些处理
if (baseName === "index.vue") {
// 读取sfc 获取code
const code = await fs.readFile(src, "utf-8");
// 通过vue-template-compiler对code进一步处理获取js部分代码
const vueScript = compiler.parseComponent(code);
// 获取ast树
const ast = parser.parse(vueScript.script.content, {
plugins: ["jsx"],
sourceType: "module",
});
// 通过traverse对ast树进行遍历
traverse(ast, {
ObjectProperty(key) {
const label = key.node.key.name;
// leadingComments为//这种注释
const value =
key.node.leadingComments && key.node.leadingComments[0].value;
// 获取组件的名称
if (key.node.key.name === "name") {
key = key.node.value.value;
tags[key] = {
description: "a global component",
attributes: tagsAttributes,
};
attrName = key;
}
if (value) {
attributesJson[`${attrName}/${label}`] = {
description: value,
};
tagsAttributes.push(label);
}
},
});
// 创建vetur文件并写入json
fs.ensureDir("./vetur");
fs.writeJSON("./vetur/tags.json", tags);
fs.writeJSON("./vetur/attributes.json", attributesJson);
}
};
- 当文件名为 index.vue 时对文件进行 sfc 的解析
- 通过 parser 函数将 code 转为 ast
- 用 traverse 对 ast 树进行遍历获取我需要的值
- 最总输出 json 文件
最后实现
在 pageage.json 中引入如下图:
还有最重要的一点在 pageage.json 引入后需要重启 vscode 去加载它。
效果图
ending
点个赞呗.