webpro-nl / knip

✂️ Find unused files, dependencies and exports in your JavaScript and TypeScript projects. Knip it before you ship it!
https://knip.dev
ISC License
7.06k stars 177 forks source link

(GraphQL Codegen plugin): Support plugins whose package name does not start with `@graphql-codegen/` #729

Closed taro-28 closed 4 months ago

taro-28 commented 4 months ago

Hello!

There are some packages in the GraphQL Codegen plugin whose name does not start with @graphql-codegen/(e.g. graphql-codegen-typescript-validation-schema), and they are currently not detected correctly by knip.

Reproduction

https://stackblitz.com/edit/aub1ebknip-graphql-codegen?file=package.json,knip.json,codegen.json

❯ npm run knip

> knip
> knip

Unused devDependencies (1)
graphql-codegen-typescript-validation-schema  package.json
Unlisted dependencies (1)
@graphql-codegen/typescript-validation-schema  codegen.json

Cause

I think it is because the plugin is implemented assuming that the package name starts with @graphql-codegen/. https://github.com/webpro-nl/knip/blob/main/packages/knip/src/plugins/graphql-codegen/index.ts#L59-L74

Suggestions

1: Return all possible package names in resolveConfig

For example, if codegen.json is the following, if any of @graphql-codegen/typescript-validation-schema, graphql-codegen-typescript-validation-schema, etc. exist in package.json, they are treated as used.

{
  "schema": "schema.graphql",
  "generates": {
    ".": {
      "plugins": ["typescript-validation-schema"]
    }
  }
}

This idea is ideal for users, but I do not know if it can be easily implemented.

2: Support full name plugin names (I think this is the better way)

For example, if codegen.json is the following, only if graphql-codegen-typescript-validation-schema exists in package.json, they are treated as used.

{
  "schema": "schema.graphql",
  "generates": {
    ".": {
      // Set the full name
      "plugins": ["graphql-codegen-typescript-validation-schema"]
    }
  }
}

Of course, GraphQL Codegen can be set up with the full name. https://github.com/dotansimha/graphql-code-generator/blob/master/packages/graphql-codegen-cli/src/plugins.ts#L8-L18

This idea would only require users to set the full name if the package name is a plugin that does not start with @graphql-codegen/, but the implementation could be as simple as a conditional branch based on whether the plugin name contains codegen- or not.

const flatPlugins = generateSet
  .filter((config): config is ConfiguredPlugin => !isConfigurationOutput(config))
  .flatMap(item => Object.keys(item))
  .map(plugin =>
    // Check if plugin name is full name
    plugin.includes('codegen-') ? plugin : `@graphql-codegen/${plugin}`
  );

I prefer this idea because there are a few plugins whose package names do not start with @graphql-codegen/, and the implementation is simple.


If the second idea is acceptable, we would like to create a PR! (I plan to modify preset as well)

webpro commented 4 months ago

Thanks @taro-28! I agree with your idea! Let's keep it simple whenever possible. If necessary we could look into copying the logic of graphql-code-generator later on and try all options (but personally I don't really understand/like this approach).

taro-28 commented 4 months ago

Thanks!

If necessary we could look into copying the logic of graphql-code-generator later on and try all options (but personally I don't really understand/like this approach).

If it seems to be more difficult to implement, I'll give it a try.