Skip to content

Instantly share code, notes, and snippets.

@tesla3327
Created November 12, 2019 21:44
Show Gist options
  • Save tesla3327/1b1d699a4c3494277c596a280e0dfe1a to your computer and use it in GitHub Desktop.
Save tesla3327/1b1d699a4c3494277c596a280e0dfe1a to your computer and use it in GitHub Desktop.
Node script for generating stats on how components in Construction Yard are used.
#!/usr/bin/env node
// Script that consumers of CY can run to obtain stats on
// how they are using CY components in their project.
const glob = require('glob');
const fs = require('fs');
// List of components re-generated on every build
const { components } = require('./components.json');
// Count occurrences of a string within a file
const getCount = (file, string) => {
let count = 0;
let index = file.indexOf(string);
while (index >= 0) {
count += 1;
index = file.indexOf(string, index + 1);
}
return count;
};
const toKebabCase = str => str
.replace(/([a-z])([A-Z])/g, '$1-$2')
.replace(/\s+/g, '-')
.toLowerCase();
const parseVueFile = (file, componentList) => {
// Find all components used
const stats = {};
componentList.forEach((component) => {
const count = getCount(file, `<${component} `)
+ getCount(file, `<${component}>`)
+ getCount(file, `<${component}\n`)
+ getCount(file, `<${toKebabCase(component)} `)
+ getCount(file, `<${toKebabCase(component)}>`)
+ getCount(file, `<${toKebabCase(component)}\n`);
if (count > 0) {
stats[component] = count;
}
});
return stats;
};
// Convert from by filename to by component name
const transformStats = stats => Object.keys(stats)
.reduce((prev, next) => {
// Get components for the file
const componentList = Object.keys(stats[next]);
componentList.forEach((component) => {
if (!prev[component]) {
prev[component] = {};
}
prev[component][next] = stats[next][component];
});
return prev;
}, {});
const timeStart = process.hrtime();
console.log(`Scanning directory for ${components.length} components...`);
glob('**/*.vue', {}, (er, files) => {
const statsByFile = {};
files.forEach((filename) => {
const file = fs.readFileSync(filename, 'utf8');
const fileStats = parseVueFile(file, components);
if (Object.keys(fileStats).length > 0) {
statsByFile[filename] = fileStats;
}
});
const [endTime] = process.hrtime(timeStart);
console.info('Completed in: %ds', endTime);
const results = {
filename: statsByFile,
component: transformStats(statsByFile),
};
// Write out file with newline at the end
fs.writeFileSync('./cy-stats.json', `${JSON.stringify(results, null, 2)}\n`);
console.log('Stats written out to: cy-stats.json');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment