unplugin-icons: vue-tsc Cannot find module '~icons/ui/info' or its corresponding type declarations.

In our project running Vite and Vue2 (through vue-demi), when running vue-tsc, we get an error:

 ERROR(vue-tsc)  Cannot find module '~icons/ui/info' or its corresponding type declarations.

tsconfig:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "baseUrl": ".",
    "typeRoots": [
      "./node_modules/@types", 
      "./node_modules/unplugin-icons/types"
    ],
    "paths": {
      "@/*": ["src/*"]
    },
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "src/**/*.d.ts",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [
    "node_modules"
  ],
  "vueCompilerOptions": {
    "experimentalCompatMode": 2
  }
}

vite.config:

const config = defineConfig(({ mode }) => {
    const isProduction = mode === "production";
    return {
        resolve: {
            alias: {
                "@": path.resolve(__dirname, "src")
            },
            dedupe: ["vue-demi"]
        },
        build: {
            minify: isProduction,
            manifest: true,
            rollupOptions: {
                input: "src/main.ts"
            }
        },
        plugins: [
            legacy({
                targets: ["ie >= 11"],
                additionalLegacyPolyfills: ["regenerator-runtime/runtime"]
            }),
            Vue2(),
            checker({
                vueTsc: true
            }),            
            Icons({
                compiler: "vue2",
                customCollections: {
                    "ui": FileSystemIconLoader(
                        "./src/assets/icons/ui")
                }
            })
        ],
        server: {
            port: 3333
        }
    };
});

Icon is src/assets/icons/ui/info.svg with the following svg-code:

<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M0 10C0 4.47715 4.47715 0 10 0C15.5228 0 20 4.47715 20 10C20 15.5228 15.5228 20 10 20C4.47715 20 0 15.5228 0 10Z" fill="currentColor"/>
    <path d="M10.47 14.1498C10.46 14.1998 10.455 14.2648 10.455 14.3448C10.455 14.5848 10.545 14.7048 10.725 14.7048C10.805 14.7048 10.89 14.6798 10.98 14.6298C11.08 14.5798 11.22 14.4948 11.4 14.3748L11.595 14.8848C11.425 15.1148 11.16 15.3498 10.8 15.5898C10.45 15.8298 10.005 15.9498 9.465 15.9498C9.005 15.9498 8.645 15.8648 8.385 15.6948C8.135 15.5148 8.01 15.2848 8.01 15.0048C8.01 14.9448 8.015 14.8948 8.025 14.8548L8.415 11.8998L8.835 8.7648L7.995 8.3148L8.115 7.6698L11.01 7.2798L11.4 7.4598L10.47 14.1498ZM10.455 5.9898C10.155 5.9898 9.885 5.8698 9.645 5.6298C9.415 5.3898 9.3 5.1198 9.3 4.8198C9.3 4.4098 9.44 4.0648 9.72 3.7848C10 3.4948 10.37 3.3498 10.83 3.3498C11.18 3.3498 11.46 3.4648 11.67 3.6948C11.88 3.9248 11.985 4.1898 11.985 4.4898C11.985 4.9298 11.855 5.2898 11.595 5.5698C11.335 5.8498 10.955 5.9898 10.455 5.9898Z" fill="#113053"/>
</svg>

I’ve see an other issue that says to add “skipLibCheck: true” to tsconfig, but this has not worked.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 20 (2 by maintainers)

Commits related to this issue

Most upvoted comments

Update for Nuxt users

The following entry in nuxt.config removed the import errors:

typescript: {
    tsConfig: {
        compilerOptions: {
            types: ["unplugin-icons/types/vue"]
        }
    }
}

Update

I was able to get this to work by replacing ~icons/ with virtual:icons/ when referencing an icon

・・・・・・

I’m experiencing this only in production with SvelteKit/Vite deploying to Vercel. My global.d.ts file has this line:

/// <reference types="unplugin-icons/types/svelte" />

and this is the error thrown when trying to build:

[vite:load-fallback] Could not load /Users/silas/Documents/Websites/projectname/~icons/material-symbols/send-outline-rounded (imported by src/lib/components/routes/ContactForm.svelte): ENOENT: no such file or directory, open '/Users/silas/Documents/Websites/projectname/~icons/material-symbols/send-outline-rounded'

Everything works perfectly in development.

We temporarily close this due to the lack of enough information. Please provide a minimal reproduction to reopen the issue. Thanks.

Why reproduction is required

The same problem has been solved with the following solution:

in tsconfig.json.

{
  ・・・
  "compilerOptions": {
    ・・・
    "types": ["unplugin-icons/types/vue"], // 修复 Cannot find module '~icons/xxx/xxx' or its corresponding type declarations.ts(2307)
    ・・・
  },
}

@antfu, any help with this one? 🙏

image

Hi @Nacho114 I actually was able to do it on SvelteKit.

Here was my solution: https://github.com/unplugin/unplugin-icons/issues/128#issuecomment-1675830394

Also prepped a CodeSandbox for you here. While checking it, here are a few things to note:

  1. Make sure to check the vite.config.ts
import Icons from 'unplugin-icons/vite';

const config: UserConfig = {
	plugins: [
		sveltekit(),
+		Icons({
+		  compiler: 'svelte',
+	   	}),
	]
};
  1. Also check your tsconfig.json
{
	"extends": "./.svelte-kit/tsconfig.json",
	"compilerOptions": {
		...,
		"strict": true,
+		"types": ["unplugin-icons/types/svelte"]
	}
}

Usual workflow when importing a new icon.

  1. I go to https://icones.js.org/
  2. See an icon you like, open it and copy something like: “ph:airplane-tilt-fill”
  3. Use that piece of string and to import do two things:
/** Step 1. ON YOUR TS FILE. */
- import IconAirplane from "ph:airplane-tilt-fill"
+ import IconAirplane from "~icons/ph/airplane-tilt-fill"

/** Step 2. ON YOUR CLI. */
- pnpm add -D "ph:airplane-tilt-fill"
+ pnpm add @iconify-json/ph


/** 
You can probably see a pattern here when importing

  Copied String: "ph:airplane-tilt-fill" -> "<icon group>:<icon name>"

  import "~icons/<icon group>/<icon name>"

  pnpm add @iconify-json/<icon group>
*/

@amirhoseinsalimi It works if you use auto-import. https://github.com/antfu/unplugin-icons#auto-importing https://github.com/antfu/unplugin-icons#use-with-resolver

I’ll leave this issue open, since i feel it should either documented that this is necessary or should be fixed

Hey!

Thanks for the quick answer 😃

So I followed steps 1 and 2.

The main difference is that:

In src/app.d.ts I have import 'unplugin-icons/types/svelte';

And I added all icons already "@iconify/json": "^2.2.123" in the package.json

But I do still get the type error:

import ChevronRight from 'virtual:icons/gg/chevron-right';

I tried to replace virtual:icons with ~icons but with the same result 😕

two way to fix it

in nuxt.config.ts

export default defineNuxtConfig({
  // ...
  typescript: {
    tsConfig: {
      compilerOptions: {
        // add it
        types: ["unplugin-icons/types/vue"],
      },
    },
  },
});

then the ./.nuxt/tsconfig.json will add it in type property.

image

now it can work well.

image

another way is that write a d.ts and add /// <reference types="unplugin-icons/types/vue" /> in the top.

image

it also can work well.

hope these way can help you. 😃