antoine-coulon / skott

All-in-one devtool to automatically analyze, search and visualize project modules and dependencies from JavaScript, TypeScript (JSX/TSX) and Node.js (ES6, CommonJS)
MIT License
643 stars 25 forks source link

Can support for vue projects be added? #142

Open wendell0316 opened 7 months ago

wendell0316 commented 7 months ago

Summary

Details

Standard questions

Please answer these questions to help us investigate your issue more quickly:

Question Answer
Would you consider contributing a PR?
antoine-coulon commented 7 months ago

Hello @wendell0316,

That's definitely something we can do yes. Let's support @vuejs in skott.

Dykam commented 4 weeks ago

Maybe of use to make it easier to see what changes need to be made, this is what I needed to do to get .vue files kind of working.

Some things I noted for myself:

import { parse } from "@vue/compiler-sfc";
import { defaultConfig, Skott } from "skott";
import { FileSystemReader } from "skott/filesystem/file-reader";
import { FileSystemWriter } from "skott/filesystem/file-writer";
import { kExpectedModuleExtensions } from "skott/modules/resolvers/base-resolver";
import { ModuleWalker, ModuleWalkerSelector } from "skott/modules/walkers/common";

kExpectedModuleExtensions.add(".vue");

export const createSkott = ({ cwd }: { cwd: string }) => {
  const moduleWalkerSelector = new ModuleWalkerSelector();
  return new Skott(
    defaultConfig,
    new FileSystemReader({ cwd, ignorePatterns: [] }),
    new FileSystemWriter(),
    new (class {
      selectAppropriateModuleWalker(fileName: string): ModuleWalker {
        if (fileName.endsWith(".vue")) {
          return {
            async walk(options) {
              const parsed = parse(options.fileContent, { filename: options.fileName });
              const moduleDeclarations = new Set<string>();

              for (const blockType of ["script", "scriptSetup"]) {
                if (parsed.descriptor[blockType]?.content) {
                  const walker = moduleWalkerSelector.selectAppropriateModuleWalker(
                    `foo.${parsed.descriptor[blockType]?.lang ?? "js"}`
                  );
                  const walkerResult = await walker.walk({
                    ...options,
                    fileContent: parsed.descriptor[blockType].content,
                    fileName: `${options.fileName}-${blockType}.${parsed.descriptor[blockType].lang ?? "js"}`,
                  });
                  for (const moduleDeclaration of walkerResult.moduleDeclarations) {
                    moduleDeclarations.add(moduleDeclaration);
                  }
                }
              }

              return { moduleDeclarations };
            },
          };
        }
        return moduleWalkerSelector.selectAppropriateModuleWalker(fileName);
      }
    })() as ModuleWalkerSelector,
    {
      failure: () => {},
      info: () => {},
      success: () => {},
      startInfo: () => () => {},
    }
  );
};
antoine-coulon commented 2 weeks ago

Hello @Dykam,

Thanks for investigating that topic, you're raising interesting points. I'll have a more precise look when I'll be back from holidays (currently on my phone).

But let me answer you few things, indeed this is not an easy thing to do from an external perspective (adding Vue support), currently the only way to make it properly work with Vue would be to extend internals. But this is not something I want to do, I would rather have plugins that we can plug in to make Vue work with skott.

skott was initially designed to natively support JS/TS plus JSX. Nonetheless I always had in mind to make skott a fit for other ecosystems or even supporting all file extensions for the JS ecosystem (Vue, Astro, etc) by making skott more flexible through some sort of plugins or runtime configuration to make it support other languages with their own parsers without having to dive into internals (I'm a huge fan of Vite or Rollup like plugin extensions).

Consequently what I can suggest is that I'll be taking a closer look at that beginning of next month and I'll be considering that enhancement and new design to make skott able to easily support Vue but also use the opportunity to make it flexible for other ecosystems/languages in general.

Dykam commented 2 weeks ago

All things considered, it was surprisingly easy to add the support, and I'm using it currently as part of a CI pipeline for cycle checking. Actual changes to make this easier are quite small, unless you of course want to redesign the API around a plugin system. My main issue is that I can no longer use renderTerminalApplication, or otherwise use the easy command line interface normally integrated. Other than that it's working pretty much flawless.

antoine-coulon commented 2 weeks ago

Glad to hear that, feel free to open a PR with the changes so that we can take a look at them together. I won't start the new design anytime soon, so it should not be a blocker