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

Next.JS Does Not Support Lucide-React Icons #54571

Closed
1 task done
jd-carroll opened this issue Aug 25, 2023 · 4 comments · Fixed by #54572
Closed
1 task done

Next.JS Does Not Support Lucide-React Icons #54571

jd-carroll opened this issue Aug 25, 2023 · 4 comments · Fixed by #54572
Labels
bug Issue was opened via the bug report template. locked

Comments

@jd-carroll
Copy link

jd-carroll commented Aug 25, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.5.0: Thu Jun  8 22:22:20 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.16.1
      npm: 9.8.1
      Yarn: 1.22.19
      pnpm: 8.5.1
    Relevant Packages:
      next: 13.4.20-canary.8
      eslint-config-next: 13.4.19
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router

Link to the code that reproduces this issue or a replay of the bug

https://codesandbox.io/p/sandbox/xenodochial-paper-gllsfk?file=/app/page.tsx:9,1

To Reproduce

  1. npx create-next-app@canary --typescript
  2. cd into dir
  3. npm install next@canary
  4. Create a new icon which uses createLucideIcon (example below)
  5. Include that icon anywhere in app
  6. Bust
import { createLucideIcon } from 'lucide-react';

export const GitHub = createLucideIcon('GitHub', [
  [
    'path',
    {
      d: 'M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z'
    }
  ]
]);

Describe the Bug

Next.JS needs to adopt the import mappings provided by lucide-react as well as add createLucideIcon to known transforms.

Expected Behavior

The icon be displayed as expected.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@jd-carroll jd-carroll added the bug Issue was opened via the bug report template. label Aug 25, 2023
@jd-carroll
Copy link
Author

Related issues:
#53605

Pull requests which solve the issue:
#53789 #53894

@jd-carroll
Copy link
Author

For anyone running into this, you can create a patch of your local version of next with the following:

  1. Change next to a static version (i.e. from "next": "^13.4.19", to "next": "13.4.19")
    (If monorepo, do that for every next dependency)
  2. Use yarn patch or pnpm patch to start a patch (or use patch-package if npm)

Change the following files (under the next dependency):

  • dist/server/config.js
  • dist/esm/server/config.js

In both of those files, change:

        "lucide-react": {
            // Note that we need to first resolve to the base path (`lucide-react`) and join the subpath,
            // instead of just resolving `lucide-react/esm/icons/{{kebabCase member}}` because this package
            // doesn't have proper `exports` fields for individual icons in its package.json.
            transform: {
                // Special aliases
                "(SortAsc|LucideSortAsc|SortAscIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/arrow-up-narrow-wide!lucide-react",
                "(SortDesc|LucideSortDesc|SortDescIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/arrow-down-wide-narrow!lucide-react",
                "(Verified|LucideVerified|VerifiedIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/badge-check!lucide-react",
                "(Slash|LucideSlash|SlashIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/ban!lucide-react",
                "(CurlyBraces|LucideCurlyBraces|CurlyBracesIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/braces!lucide-react",
                "(CircleSlashed|LucideCircleSlashed|CircleSlashedIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/circle-slash-2!lucide-react",
                "(SquareGantt|LucideSquareGantt|SquareGanttIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/gantt-chart-square!lucide-react",
                "(SquareKanbanDashed|LucideSquareKanbanDashed|SquareKanbanDashedIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/kanban-square-dashed!lucide-react",
                "(SquareKanban|LucideSquareKanban|SquareKanbanIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/kanban-square!lucide-react",
                "(Edit3|LucideEdit3|Edit3Icon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/pen-line!lucide-react",
                "(Edit|LucideEdit|EditIcon|PenBox|LucidePenBox|PenBoxIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/pen-square!lucide-react",
                "(Edit2|LucideEdit2|Edit2Icon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/pen!lucide-react",
                "(Stars|LucideStars|StarsIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/sparkles!lucide-react",
                "(TextSelection|LucideTextSelection|TextSelectionIcon)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/text-select!lucide-react",
                // General rules
                "Lucide(.*)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/{{ kebabCase memberMatches.[1] }}!lucide-react",
                "(.*)Icon": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/{{ kebabCase memberMatches.[1] }}!lucide-react",
                "*": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/{{ kebabCase member }}!lucide-react"
            }
        },

To:

        "lucide-react": {
            // Note that we need to first resolve to the base path (`lucide-react`) and join the subpath,
            // instead of just resolving `lucide-react/esm/icons/{{kebabCase member}}` because this package
            // doesn't have proper `exports` fields for individual icons in its package.json.
            transform: {
                // Alias for createLucideIcon
                createLucideIcon: 'modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/createLucideIcon!lucide-react',
                // Alias for icons
                icons: 'modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/index!lucide-react',
                // General rules
                "Lucide(.*)": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/{{ kebabCase memberMatches.[1] }}!lucide-react",
                "(.*)Icon": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/{{ kebabCase memberMatches.[1] }}!lucide-react",
                "*": "modularize-import-loader?name={{ member }}&from=default&as=default&join=../esm/icons/{{ kebabCase member }}!lucide-react"
            }
        },

Save the patch

If you're using yarn, you need to run yarn install after you saved the patch with yarn patch-commit (maybe also with pnpm and npm)

Note: The order of the transforms is really important, specifically the wild card must come last

Don't be like me and waste hours trying to debug because you put a transform after the catch all wild card...

shuding added a commit that referenced this issue Aug 25, 2023
…ig (#54572)

## Implementation

Base on #54530, we're implementing a `optimize_barrel` transform to
optimize barrel files to only export the names we need. If the
transformed file isn't a "barrel file", we just re-export the names from
it without any transformation.

Take `lucide-react` as an example, with #54530 we are able to transform

```js
import { IceCream } from 'lucide-react'
```

to 

```js
import { IceCream } from '__barrel_optimize__?names=IceCream!=!lucide-react?__barrel_optimize_noop__=IceCream'
```

And then, we apply that new request with a new Webpack module rule to
use the SWC loader with option `optimizeBarrelExports: ['IceCream']`,
which eventually got passed to this new `optimize_barrel` transform and
does the optimization.

## Notes

We'll have to add a new `getModularizeImportAliases` alias list to map
`lucide-react` to the ESM version, as we have the `['main', 'module']`
resolve order for the server compiler. Otherwise this optimization
doesn't work in that compiler.

There's no e2e test added because it's already covered by the
`modularize-imports` test as we removed the default `lucide-react`
transform rules and it still works.

We'll need to test other libs before migrating them to the new
`optimizePackageImports` option.

---

Closes #54571, closes #53605, closes #53789, closes #53894, closes
#54063.
@arvinxx
Copy link

arvinxx commented Aug 26, 2023

which next version will solve this problem ?

@github-actions
Copy link
Contributor

github-actions bot commented Sep 9, 2023

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot added the locked label Sep 9, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. locked
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants