Skip to content

Instantly share code, notes, and snippets.

@Illyism
Last active November 15, 2024 16:42
Show Gist options
  • Save Illyism/96480916c2a24e0032fece5d08ff2d2b to your computer and use it in GitHub Desktop.
Save Illyism/96480916c2a24e0032fece5d08ff2d2b to your computer and use it in GitHub Desktop.
Detects unused files in Next.js
// grab all the files in src/
import { glob } from 'glob'
import { basename, extname } from 'node:path'
function getName(a: string) {
return basename(a, extname(a))
}
function isSameFileName(fpA, fpB) {
if (fpA === fpB) return false // same file
const fileNameA = getName(fpA)
const fileNameB = getName(fpB)
if (fileNameA === fileNameB) {
// if it's "index.ts" or "index.js" then it's not a conflict, check the folder above also
if (fileNameA === 'index.ts' || fileNameA === 'index.js') {
const folderA = fpA.split('/').slice(0, -1).join('/')
const folderB = fpB.split('/').slice(0, -1).join('/')
return folderA === folderB
}
return true
}
}
const fileContents = {}
function findFileName(file: string, filePaths: string[]) {
for (const otherFilePath of filePaths) {
if (file === otherFilePath) continue
if (fileContents[otherFilePath].includes(file.replace(/^(app|components|lib|hooks)\//, '@/'))) {
return true
}
const fileName = file.split('/').pop()
if (fileContents[otherFilePath].includes(fileName)) {
return true
}
// without extension
const fileNameWithoutExtension = fileName.split('.')[0]
if (fileContents[otherFilePath].includes(fileNameWithoutExtension)) {
return true
}
}
return false
}
async function checkUnusedDependencies(filePaths: string[]) {
// for all our files, check if they are imported in any other file
// if not, then it's an unused dependency
const unusedDependencies = []
// filenames
for (const filePath of filePaths) {
const isFound = findFileName(filePath, filePaths)
if (!isFound) {
unusedDependencies.push(filePath)
}
}
if (unusedDependencies.length > 0) {
console.log('Found unused dependencies:')
}
for (const unusedDependency of unusedDependencies) {
console.log(unusedDependency)
}
if (unusedDependencies.length > 0) {
process.exit(1)
}
}
async function main() {
const filePaths = await glob([
'{app,components,lib,hooks}/**/*.{ts,tsx,vue,js,json}',
'*.html'
], {
ignore: ['**/node_modules/**', '**/*.d.ts'],
})
for (const filePath of filePaths) {
const foo = Bun.file(filePath)
fileContents[filePath] = await foo.text()
}
checkUnusedDependencies(filePaths)
console.log('👍')
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment