jscodeshift - get count of all imports from a module in project

646 views Asked by At

I'm playing around with jscodeshift.

My goal is to get count of all imports from a particular module in a project

import { Circle, Triangle, Rectangle } from 'geometry';

results in

{ Circle: 1, Triangle: 1, Rectangle: 1 }

I have kind of achieved what I wanted here But the only issue is that I want these stats for a whole project instead of single file.

Any idea how can I achieve this?

2

There are 2 answers

1
top16Dev On

Not sure if I understand this correctly, are you trying to import everything from within a module without having to explicitly type their names (Circle, Triangle, etc)? Or this might help:

export const Foo = 1;
export const Bar = 2;

// geometry2.js|ts
export const Biz = 3;

// index.js|ts 
import * as counts from './geometry';
import * as counts2 from './geometry2';

const data = { ...counts, ...counts2 };
console.log(data); // logs {Foo: 1, Bar: 2, Biz: 3}
0
Zhe On

I am afraid that you are using the wrong tool for the job. jscodeshift, as the name suggests, is a tool that modifies your codebase by analyzing and transforming ASTs, and it works on the file level. In other words, it is meant for modifying file one by one, not for statically analyzing a codebase.

What you showed in the link is really using the parser and the AST tree walker (node visitor) that jscodeshift depends on to aggregate the statistics. For your goal, you need to write a nodeJS script that uses the glob tool to find all the js files, a parser that analyzes each of the file (e.g. acorn or @babel/parser used as default in jscodeshift), and a matching walker (acorn-walk or @babel/traverse) to find the node and add it to your statistics. Here is an example using glob, @babel/parser and @babel/traverse (just as an example, I haven't run the code)

import * as glob from 'glob';
import * as fs from 'node:fs';
import * as parser from '@babel/parser';
import traverse from '@babel/traverse';

glob('**/*.js', {}, (err, files) => {
    if (err) {
        // handle error
    }

    files.forEach(file => {
        const code = fs.readFileSync(file, 'utf-8');
        const ast = parser.parse(code, {
            sourceType: 'module'
        });
        traverse(ast, {
            ImportDeclaration (path) {
                // handle your statistics
            }
        });
    });
});