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

🐛 React lazy import path not being picked up #839

Open ryan-tote opened 1 week ago

ryan-tote commented 1 week ago

Prerequisites

Reproduction url

https://codesandbox.io/p/sandbox/ls97j5?file=%2Fsrc%2FApp.tsx%3A25%2C5

Reproduction access

Description of the issue

An ordinary react lazy where the import path is inside the function works fine.

const Button = lazy(() => {
  return import("./components/Button").then((mod) => {
    return { default: mod.Button };
  });
});

But when you move the import path to a separate function it no longer follows the function path.

const getComponentFile = () => {
  return import("./components/Button");
};

const Button = lazy(() => {
  return getComponentFile().then((mod) => {
    return { default: mod.Button };
  });
});

const preloadComponent = () => {
  void getComponentFile();
};

Knip believes that the Button component is not being used so it flags it up as an unused export

webpro commented 5 days ago

This is expected behavior.

Did you try your luck by adding --include-libs? Your CSB doesn't have a terminal so I can't try.

ryan-tote commented 4 days ago

Oh interesting, didn't know that.

I saw that dynamic imports don't work on the docs https://knip.dev/guides/handling-issues#dynamic-import-specifiers but this isn't exactly a dynamic import.

--include-libs does work but incurs a performance penalty. Does seem a bit weird that we need to add that flag since this isn't library code.

webpro commented 4 days ago

This mode is disabled by default, because it incurs a performance penalty.

Docs should be improved, indeed this isn't only about library code.

Glad it does seem to do the trick for you!