| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- /* eslint-disable */
- import { extractImports, findJSAndImports } from './esm-check-migration.mjs'
- import path from 'node:path'
- import fs from 'node:fs'
- const imports = await findJSAndImports(
- ['app', 'modules'].map(dir => path.resolve(dir))
- )
- const entryPoint = fs.existsSync('app.js') ? 'app.js' : 'app.mjs'
- imports.set(path.resolve(entryPoint), extractImports(entryPoint))
- const moduleImports = new Map()
- imports.forEach((deps, module) => {
- for (const dep of deps) {
- if (!moduleImports.has(dep)) {
- moduleImports.set(dep, new Set())
- }
- moduleImports.set(dep, moduleImports.get(dep).add(module))
- }
- })
- const soloImports = new Map()
- moduleImports.forEach((importedBy, module) => {
- if (importedBy.size === 1) {
- soloImports.set(module, [...importedBy][0])
- }
- })
- console.log(soloImports)
- for (const [module, importedBy] of soloImports) {
- if (!moduleImports.has(importedBy)) {
- console.log(
- `${module} is only imported by ${importedBy}, which has no other imports`
- )
- }
- if (soloImports.has(importedBy)) {
- console.log(
- `${module} is only imported by ${importedBy}, which is only imported by ${soloImports.get(importedBy)}`
- )
- }
- const chains = findDependencyChainsToTarget(imports, module)
- const conversionsToMake = chains.reduce((conversions, chain) => {
- chain.forEach(dep => {
- conversions.add(dep)
- })
- return conversions
- }, new Set())
- if (conversionsToMake.length < 10) {
- console.log(
- `To convert ${module}, would need to convert: ${[...conversionsToMake].length}`
- )
- }
- }
- // --- Circular dependency detection ---
- function findCircularDependencies(importsMap) {
- const cycles = []
- const visited = new Set()
- const stack = []
- function dfs(file, pathStack) {
- if (pathStack.includes(file)) {
- // Cycle detected
- const cycleStart = pathStack.indexOf(file)
- cycles.push(pathStack.slice(cycleStart).concat(file))
- return
- }
- if (!importsMap.has(file)) return
- pathStack.push(file)
- for (const imp of importsMap.get(file)) {
- const resolvedImp = path.resolve(imp)
- dfs(resolvedImp, pathStack)
- }
- pathStack.pop()
- }
- for (const file of importsMap.keys()) {
- dfs(file, [])
- }
- return cycles
- }
- const cycles = findCircularDependencies(imports)
- if (cycles.length > 0) {
- console.log('Circular dependencies found:')
- for (const cycle of cycles) {
- console.log(' ' + cycle.join(' -> '))
- }
- } else {
- console.log('No circular dependencies detected.')
- }
- // --- Find all chains of dependencies to a target file ---
- function findDependencyChainsToTarget(importsMap, targetPath) {
- const chains = []
- const resolvedTarget = path.resolve(targetPath)
- function dfs(current, pathStack) {
- if (pathStack.includes(current)) return // avoid cycles
- pathStack.push(current)
- if (current === resolvedTarget) {
- chains.push([...pathStack])
- pathStack.pop()
- return
- }
- if (!importsMap.has(current)) {
- pathStack.pop()
- return
- }
- for (const imp of importsMap.get(current)) {
- const resolvedImp = path.resolve(imp)
- dfs(resolvedImp, pathStack)
- }
- pathStack.pop()
- }
- for (const file of importsMap.keys()) {
- if (file === resolvedTarget) continue // skip self
- dfs(file, [])
- }
- return chains
- }
- // Example usage: set your target file path here
- const targetFile =
- '/Users/arumble/Documents/Projects/internal/services/web/app/src/Features/Analytics/AnalyticsManager.js' // <-- change to your target
- const chains = findDependencyChainsToTarget(imports, targetFile)
- if (chains.length > 0) {
- console.log(`Dependency chains leading to ${targetFile}:`)
- for (const chain of chains) {
- console.log(' ' + chain.join(' -> '))
- }
- } else {
- console.log(`No dependency chains found leading to ${targetFile}.`)
- }
- const conversionsToMake = chains.reduce((conversions, chain) => {
- chain.forEach(dep => {
- conversions.add(dep)
- })
- return conversions
- }, new Set())
- console.log([...conversionsToMake].join(' '))
|