Open mgcrea opened 9 months ago
I'm totally in favour of dropping non-suffixed/prefixed names from our exports starting from v1.0, preferably only keeping either Lucide<IconName>
or <IconName>Icon
.
Hmm, I don't know about dropping it. It's just a matter of taste I think. Also, that means that everyone who updates to v1 should refactor their project and rename all their imports and icon components. Nobody will like that..
But I get your point. When using the library I think I ran into this a few times. So the solution I want to propose is the ability to change this by overriding the type declarations.
In your project, you could create a typing file like lucide-react.d.ts
or whatever you want to name it.
And include this content:
// lucide-react.d.ts
declare module "lucide-react" {
export * from "lucide-react/dist/lucide-react.prefixed";
// This will re-export all exports but only includes the icons with prefixes and other library types
}
In every package, we can create a new entry file that includes different import styles.
lucide-react/dist/lucide-react.prefixed
, only includes export like LucideHome, LucideX, LucideMenu
lucide-react/dist/lucide-react.suffixed
, only includes export like HomeIcon, XIcon, MenuIcon
I've already tested it, and it works. But need to rewrite some things to generate multiple aliases files.
Thanks for writing all this up @mgcrea ! The workaround by @ericfennis would be the MVP and perhaps solve already the issue.
Regarding: "Nobody will like that.." I think this is a "do it once and get over it"-migration. In contrast, the "pollution" when using multiple libraries will stay an ongoing issue. And with the drive towards configless project setups, I'd argue that it would be a huge win to just drop unsuffxed/unprefixed icons. Also from an educational perspective, which I have, it is difficult to explain beginners the workaround.
Thanks Eric for guiding me to this issue page.
I am only every using the suffixed version of the icons, like "LinkIcon", to keep them distinguishable from other naming convention like 'Link' from the next/link package.
As you pointed out, I created the file lucide-react.d.ts
in the main dir of my NextJS project. As I intent to use the suffixed version, I included the following content:
declare module 'lucide-react' {
export * from 'lucide-react/dist/lucide-react.suffixed';
// This will re-export all exports but only includes the icons with prefixes and other library types
}
Typescript is immediately throwing errors, like:
Module '"lucide-react"' has no exported member 'AlertCircleIcon'.
I tried to check node_modules/lucide-react/dist
and it seems there is no lucide-react.suffixed folder in there (I have to say though, that I am not well aversed with handling node-modules).
Can you point me in the right direction? Thanks!
@tillka yeah sorry maybe I confused you a bit. This is a proposal for a fix. This is still not implemented yet.
@tillka yeah sorry maybe I confused you a bit. This is a proposal for a fix. This is still not implemented yet.
Oh, thought it was an MVP. Then, you can put me on the wait list for this feature to be implemented. ;)
As React libs like shadcn ui becoming more popular, component composition will be the default for many devs. I lost embarrassing amount of time on icons auto import.
This auto-import pollution is THE most annoying thing I run into on a daily basis. "typescript.preferences.autoImportFileExcludePatterns": ["lucide-react"], just stop exporting icons as Calendar, Section, Container. What should devs call their components?
"typescript.preferences.autoImportFileExcludePatterns": ["lucide-react"], then create Icons.tsx , manually import { Check, ChevronDown } from 'lucide-react' export const ChevronDownIcon = ChevronDown .. Adding a config file for a icon package to thousands of config files frontend project is not ideal. I already lost enough time because of this.
So I also struggle with this, permanently. We solved with a small vite plugin that reexports only the right icons:
function LucideIconPlugin(): Plugin {
return {
name: "lucide-icon-plugin",
buildStart: async () => {
const declarations = await readFile(
"node_modules/lucide-react/dist/lucide-react.d.ts",
"utf-8",
);
const iconNames = new Set(declarations.match(/(?<=as )[a-zA-Z0-9]+Icon/g));
const jsFile = `export * from "lucide-react/dist/esm/lucide-react";\n`;
const declarationFile =
'import { Icon } from "lucide-react";\n' +
[...iconNames]!
.map((icon) => `declare const ${icon}: import("lucide-react").LucideIcon;\n`)
.join("");
writeFileSync("libs/components/icons.gen.d.ts", declarationFile);
writeFileSync("libs/components/icons.gen.js", jsFile);
},
};
}
This will create:
// icons.gen.js
export * from "lucide-react/dist/esm/lucide-react";
// icons.gen.d.ts
declare const AArrowDownIcon: import("lucide-react").LucideIcon;
declare const AArrowUpIcon: import("lucide-react").LucideIcon;
declare const ALargeSmallIcon: import("lucide-react").LucideIcon;
declare const AccessibilityIcon: import("lucide-react").LucideIcon;
declare const ActivityIcon: import("lucide-react").LucideIcon;
...
Now just ignore the lucide-react imports in VSCode:
{
"typescript.preferences.autoImportFileExcludePatterns": [
"lucide-react"
]
}
And now TS suggestions only show the icons with suffix:
Package
Description
I've started to use
lucide-react
recently and the unsuffixed icons (eg.File
instead ofFileIcon
,Link
vs.LinkIcon
) do mess quite a bit with my workflow as it tends to pollute auto-complete/auto-import for similarly named objects (eg. Typescript typeFile
, or the commonLink
component from routers), it's confusing and I'm wasting (arguably little time) on this every time I encounter a conflict.Ideally I think it would be wise to drop the unsuffixed exports before tagging
1.0
as it leads to duplication/confusion but I guess people might not want such breaking change.So I'm wondering if we could have an optional export without the unsuffixed components:
import { FileIcon, LinkIcon } from "lucide-react/icons"
;Then use something like vscode
typescript.preferences.autoImportFileExcludePatterns
to ignore the base path with every export from polluting autocomplete.Use cases
I would lead to a better developer experience when importing icons.
Checklist