vite-plugin-deadcodes
Version:
Vite plugin to detect unused files. JS, TS, React, Vue projects are supported.
127 lines (124 loc) • 4.71 kB
JavaScript
import path from 'path';
import fs from 'fs';
import glob from 'glob';
import uniq from 'lodash.uniq';
import { minimatch } from 'minimatch';
const getProjectFiles = (dir) => {
const parttern = path.join(dir, '**/*');
const files = glob.sync(parttern, {
nodir: true,
});
return files;
};
// remove query and uniq
const formatAndUniqLoadedFiles = (files) => {
const formattedFiles = files.map(item => {
const segments = item.split('?');
return segments[0];
});
const result = uniq(formattedFiles);
return result;
};
const getUnusedFiles = ({ allFiles, loadedFiles, excludes }) => {
const rawUnusedFiles = allFiles.filter((item) => !loadedFiles.some((loadedFile) => loadedFile.includes(item)));
const unusedFiles = excludes.length
? rawUnusedFiles.filter((item) => !excludes.some((exclude) => minimatch(item, exclude)))
: rawUnusedFiles;
return { rawUnusedFiles, unusedFiles };
};
const generatePluginConfig = (rawOptions = {}) => {
const excludes = Array.isArray(rawOptions.excludes) ? rawOptions.excludes : [];
const emit = rawOptions.emit === false ? false : (typeof rawOptions.emit === 'string' ? rawOptions.emit : undefined);
return {
sourceDir: rawOptions.src || path.join(process.cwd(), 'src'),
console: rawOptions.console || false,
emit,
excludes,
};
};
function vitePluginDeadcodes(rawOptions = {}) {
const pluginOptions = generatePluginConfig(rawOptions);
const loadedFiles = [];
return {
name: 'vite-plugin-deadcodes',
apply(config, { command }) {
return command === 'build';
},
// config() {
// },
// https://rollupjs.org/plugin-development/#load
load(id) {
if (id.includes(pluginOptions.sourceDir)) ;
},
// transform: {
// order: 'pre',
// handler(code, id) {
// if (id.includes('config.sku-id')) {
// console.log('transform', id, code);
// }
// if (id.includes(pluginOptions.sourceDir)) {
// filesInLoadTransform.push(id);
// }
// },
// },
transform(code, id) {
if (id.includes(pluginOptions.sourceDir)) ;
},
moduleParsed(moduleInfo) {
const id = moduleInfo.id;
if (id.includes(pluginOptions.sourceDir)) {
loadedFiles.push(id);
}
},
writeBundle(options, bundle) {
// console.log('vite-plugin-deadcodes writeBundle', options);
const formattedLoadedFiles = formatAndUniqLoadedFiles(loadedFiles);
const allFiles = getProjectFiles(pluginOptions.sourceDir);
const {
// rawUnusedFiles,
unusedFiles } = getUnusedFiles({
allFiles: allFiles,
loadedFiles: formattedLoadedFiles,
excludes: pluginOptions.excludes,
});
// const formattedFilesInLoadHook = formatAndUniqLoadedFiles(filesInLoadHook);
// const formattedFilesInLoadTransform = formatAndUniqLoadedFiles(filesInLoadTransform);
const result = {
unusedFiles: {
total: unusedFiles.length,
files: unusedFiles,
},
// rawUnusedFiles: {
// total: rawUnusedFiles.length,
// files: rawUnusedFiles,
// },
// loadedFiles: {
// total: formattedLoadedFiles.length,
// files: formattedLoadedFiles,
// },
// filesInLoadHook: {
// total: formattedFilesInLoadHook.length,
// files: formattedFilesInLoadHook,
// },
// filesInLoadTransform: {
// total: formattedFilesInLoadTransform.length,
// files: formattedFilesInLoadTransform,
// },
allFiles: {
total: allFiles.length,
files: allFiles,
},
};
if (pluginOptions.console) {
console.log('vite-plugin-deadcodes', result);
}
if (pluginOptions.emit !== false) {
const emitFileName = typeof pluginOptions.emit === 'string'
? pluginOptions.emit
: path.join(process.cwd(), 'deadcodes.json');
fs.writeFileSync(emitFileName, JSON.stringify(result), { encoding: 'utf-8' });
}
},
};
}
export { vitePluginDeadcodes as default };