Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loadable-components with resolveComponent #522

Closed
alexeyr-ci opened this issue Feb 23, 2024 · 17 comments
Closed

loadable-components with resolveComponent #522

alexeyr-ci opened this issue Feb 23, 2024 · 17 comments
Labels
feature request Feature request

Comments

@alexeyr-ci
Copy link

I am not sure if it should be considered a feature request or a bug (or a plugin request, for that matter).

In this loadable-components example if we remove LoadableOrange

// components.js
export const Apple = () => 'Apple!'
export const Orange = () => 'Orange!'
// loadable.js
const LoadableApple = loadable(() => import('./components'), {
  resolveComponent: (components) => components.Apple,
})

Knip will mark Apple and Orange as unused, but Apple is actually used (and Orange is not).

@alexeyr-ci alexeyr-ci added the feature request Feature request label Feb 23, 2024
@alexeyr-ci
Copy link
Author

On further thought, probably a plugin request. Should I close this and post to #483?

@webpro
Copy link
Collaborator

webpro commented Feb 23, 2024

Eventually this is based on a regular import() call, would be a core feature. Probably not a candidate for a plugin, since it's dots that'll have to be connected during AST traversal.

By the way, the fact that Knip no longer detects this is a result of the v4 refactoring. In v3 this might work as expected.

Sooner or later I hope to find the time and re-implement some of findReferences within files myself, which will fix this issue.

@alexeyr-ci
Copy link
Author

Thanks!

@alexeyr-ci
Copy link
Author

In v3 this might work as expected.

It does. Even more, v3 detects some unused exports v5 doesn't on our project. So I'm switching to it for now (though I didn't check if there are true positives which v5 detects and v3 doesn't; probably should do that before merging).

@alexeyr-ci
Copy link
Author

v3 detects some unused exports v5 doesn't on our project

If you don't already know cases like that, I'll try to minimize, but not sure it'll work; this is a large project and one I can't share if I can't minimize.

@webpro
Copy link
Collaborator

webpro commented Feb 24, 2024

The disadvantage of v3 is that it does not have the improved handling of namespace related cases that v5 has (https://knip.dev/blog/knip-v5). I had to make the sacrifice in order to allow this and future improvements and keep it fast.

Feel free to set up cases you'd like to see covered, but no worries this point, you can also submit bug reports when it's (pre) released.

@alexeyr-ci
Copy link
Author

Is there a way to see why v5 thinks a particular export is used (when v3 correctly detects it isn't)?

@webpro
Copy link
Collaborator

webpro commented Feb 27, 2024

Try knip --trace

@shi-finnn-sportsbet
Copy link

shi-finnn-sportsbet commented Feb 27, 2024

+1 would love reimplementation of this in v5 (or v6)
I'm digging the performance increase from last I tried rolling out Knip to my project with v3, but not detecting usage of loadable components is a dealbreaker.

@webpro
Copy link
Collaborator

webpro commented Feb 28, 2024

The challenge in this example case is that it requires the types of loadable to understand resolveComponent is a function with the exported object as first argument, etc. Not trivial :)

Just saying, dynamic imports in general should be handled fine by Knip, see these fixtures for examples:

@coryhouse
Copy link

coryhouse commented Mar 18, 2024

Hi @webpro - Loving Knip!

I believe I've found another example of this issue: React Router lazy imports:

const routes = [
  {
    path: "operations",
    // This dynamic import isn't found, so Knip reports this file as unused.
    lazy: () => import("../pages/ServiceCentersHandler"),
  }
]

Any suggestions?

@webpro
Copy link
Collaborator

webpro commented Mar 18, 2024

What's the issue/output? This usage of import("../pages/ServiceCentersHandler") tells me the default export is used?

@coryhouse
Copy link

The output from knip with this pattern:

Analyzing workspace ....
Unused exports (50)
loader     function  src/pages/ServiceCentersHandler.tsx:13:17                                           
Component  function  src/pages/ServiceCentersHandler.tsx:20:17                                           
Component  unknown   src/pages/dispatch/Dispatch.tsx:3:14                                                
Component  unknown   src/pages/inbound/InboundLayout.tsx:23:14  

Each component that's lazy loaded this way shows as an unused export.

@webpro
Copy link
Collaborator

webpro commented Mar 18, 2024

I see, that seems to be a different issue, quite React Router specific? Feel free to open a new issue for this, ideally with a minimal reproduction.

@coryhouse
Copy link

I see, that seems to be a different issue, quite React Router specific? Feel free to open a new issue for this, ideally with a minimal reproduction.

Thanks Lars! I just opened #556.

@webpro webpro closed this as completed in 6c1c3f1 Mar 24, 2024
webpro added a commit that referenced this issue Mar 24, 2024
@webpro
Copy link
Collaborator

webpro commented Mar 24, 2024

🚀 This issue has been resolved in v5.3.0. See Release 5.3.0 for release notes.

@webpro
Copy link
Collaborator

webpro commented Mar 24, 2024

Please see https://knip.dev/guides/handling-issues#external-libs

The case of @coryhouse is still not resolved unfortunately. I think it's an issue with either TypeScript or the types of the external lib. Rule of thumb: if "Find references" in the IDE (e.g. VS Code) does not find references, Knip will likely do the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request Feature request
Projects
None yet
Development

No branches or pull requests

4 participants