Created
May 19, 2023 03:19
-
-
Save vhenzl/ceb92701ce66037077a14f11bcbb6fdc to your computer and use it in GitHub Desktop.
Script to find all imports from a module in JS/TS code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env node | |
// Based on https://github.com/montlebalm/find-js-imports | |
import { readFileSync } from 'fs'; | |
import { basename } from 'path'; | |
import glob from 'glob'; | |
import { fileURLToPath } from 'url'; | |
// https://gist.github.com/manekinekko/7e58a17bc62a9be47172 | |
const IMPORT_RX = /^import (?:["'\s]*([\w*{}\n, ]+) from\s*)?["'\s]*([.@\w\/_-]+)["'\s]*;?/gm; | |
function getFileMatches(contents, moduleName) { | |
const imports = getImports(contents); | |
return imports.find(info => info.name === moduleName); | |
} | |
function getImports(contents) { | |
const imports = []; | |
contents.replace(IMPORT_RX, (match, argString, name) => { | |
const args = splitImportedArgs(argString); | |
if (!args) return; | |
imports.push({name, args}); | |
}); | |
return imports; | |
} | |
function splitImportedArgs(argString) { | |
// This can happen when importing css e.g., import 'style.css' | |
if (!argString) return; | |
const args = argString | |
.replace(/^{\s*/, '') | |
.replace(/\s*}$/, '') | |
.split(/\s*,\s*/); | |
return args.reduce( | |
(memo, arg) => { | |
const parts = arg.split(/\s+as\s+/); | |
const [name, alias] = parts; | |
memo[name] = alias || name; | |
return memo; | |
}, | |
{} | |
); | |
} | |
function main() { | |
const args = process.argv.slice(2); | |
if (args.length !== 2) { | |
console.error(` | |
Two arguments expected: glob search patter and module name. | |
Example: | |
${basename(fileURLToPath(import.meta.url))} \'src/**/*.{js,ts,tsx}\' react` | |
); | |
process.exit(1); | |
} | |
const [pattern, moduleName] = args; | |
const globOptions = { | |
ignore: ['**/node_modules/**'], | |
}; | |
glob(pattern, globOptions, (err, paths) => { | |
if (err) throw new Error(err); | |
const files = paths.reduce( | |
(memo, path) => { | |
const contents = readFileSync(path, 'utf-8'); | |
const matches = getFileMatches(contents, moduleName); | |
if (matches) memo.push(Object.assign({path}, matches)); | |
return memo; | |
}, | |
[] | |
); | |
console.log(files); | |
console.log(new Set(files.map(x => x.path).sort())); | |
console.log(new Set(files.flatMap(x => Object.keys(x.args)).sort())); | |
}); | |
} | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment