vue-sfc-inspector
Version:
Analyze Vue SFC script setup adoption
80 lines (77 loc) • 2.17 kB
JavaScript
import { readFile } from 'node:fs/promises';
import { parse } from '@vue/compiler-sfc';
import fg from 'fast-glob';
function hasCompositionAPI(content) {
if (/setup\s*\(/.test(content))
return true;
if (/defineComponent/.test(content))
return true;
if (/import\s+\{[^}]*\b(?:ref|reactive|computed|watch|onMounted|onUnmounted)\b[^}]*\}\s+from\s+['"]vue['"]/.test(content)) {
return true;
}
return false;
}
async function classifyVueFiles(dir = ".", options = {}) {
try {
const files = await fg("**/*.vue", {
cwd: dir,
ignore: ["**/node_modules/**"]
});
let scriptSetup = 0;
let compositionAPI = 0;
let optionsAPI = 0;
const fileDetails = [];
for (const file of files) {
const source = await readFile(`${dir}/${file}`, "utf8");
const { descriptor } = parse(source);
const filePath = `${dir}/${file}`;
if (descriptor.scriptSetup) {
scriptSetup++;
if (options.includeDetails) {
fileDetails.push({ path: filePath, type: "scriptSetup" });
}
} else if (descriptor.script) {
if (hasCompositionAPI(descriptor.script.content)) {
compositionAPI++;
if (options.includeDetails) {
fileDetails.push({ path: filePath, type: "compositionAPI" });
}
} else {
optionsAPI++;
if (options.includeDetails) {
fileDetails.push({ path: filePath, type: "optionsAPI" });
}
}
}
}
const withSetup = scriptSetup;
const withoutSetup = compositionAPI + optionsAPI;
const result = {
scriptSetup,
compositionAPI,
optionsAPI,
total: files.length,
withSetup,
withoutSetup
};
if (options.includeDetails) {
result.files = fileDetails;
}
return result;
} catch (error) {
console.error(error);
const errorResult = {
scriptSetup: 0,
compositionAPI: 0,
optionsAPI: 0,
total: 0,
withSetup: 0,
withoutSetup: 0
};
if (options.includeDetails) {
errorResult.files = [];
}
return errorResult;
}
}
export { classifyVueFiles as c };