Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vite Dev Server throws error when resolving external path from importmap

Tags:

vuejs3

vite

Environment

  • Chrome: 113.0.5672.92
  • Vite: 4.3.6

Reproducing Environment

https://github.com/UedaTakeyuki/MyVue3Scaffold2

What is happen

In my Vue3 application, I tried to use libraries from CDN with following importmap script in the index.html file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
    <!-- https://stackoverflow.com/a/62282239/11073131 -->
    <script type="importmap">
      {
        "imports": {
          "vue": "https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.prod.js",
          "vuetify": "https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.esm.js",
          "vue-router": "https://cdn.jsdelivr.net/npm/vue-router@4/dist/vue-router.esm-browser.js",
          "@vue/devtools-api": "https://cdn.jsdelivr.net/npm/@vue/devtools-api@6/lib/esm/index.js"
        }
      }
    </script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

And set vuetify as external at the vite.config.ts file:

  build: {
    rollupOptions: {
      external: [
        'vue',
        'vuetify',
        'vue-router',
      ],

Then import vuetify at main.js as follows:

import { createApp } from 'vue'
import App from './App.vue'
import Home from '/src/views/Home.vue'
import About from '/src/views/About.vue'
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import { createVuetify } from 'vuetify'

Then, run LocalServer and brows it, the error Failed to resolve import "vuetify" from "src/main.js". occurred.

enter image description here

Question

First of all, Does vite support the importmap by design? Or are there any wrong or mistaken steps in my App? I'm totally confused, any suggestions are welcome.

like image 229
Ueda Takeyuki Avatar asked Aug 09 '26 20:08

Ueda Takeyuki


1 Answers

This is a current issue in Vite, where dev server tries to resolve inputs it shouldn't. Looks like they are working on it. There is a proposed workaround where you create a plugin that ignores given imports. I tried it out and it does work.

Just add the code from the workaround to your vite.config.js:

function viteIgnoreStaticImport(importKeys) {
  return {
    name: "vite-plugin-ignore-static-import",
    enforce: "pre",
    // 1. insert to optimizeDeps.exclude to prevent pre-transform
    config(config) {
      config.optimizeDeps = {
        ...(config.optimizeDeps ?? {}),
        exclude: [...(config.optimizeDeps?.exclude ?? []), ...importKeys],
      };
    },
    // 2. push a plugin to rewrite the 'vite:import-analysis' prefix
    configResolved(resolvedConfig) {
      const VALID_ID_PREFIX = `/@id/`;
      const reg = new RegExp(
        `${VALID_ID_PREFIX}(${importKeys.join("|")})`,
        "g"
      );
      resolvedConfig.plugins.push({
        name: "vite-plugin-ignore-static-import-replace-idprefix",
        transform: (code) =>
          reg.test(code) ? code.replace(reg, (m, s1) => s1) : code,
      });
    },
    // 3. rewrite the id before 'vite:resolve' plugin transform to 'node_modules/...'
    resolveId: (id) => {
      if (importKeys.includes(id)) {
        return { id, external: true };
      }
    },
  };
}

and then add the plugin to your config:

export default defineConfig({
  plugins: [
     vue(),
     viteIgnoreStaticImport(["vuetify"]) // <---- pass in the modules you want to ignore
  ],
  ...

And that is all. Just don't forget to remove it once the issue is resolved by Vite.

like image 142
Moritz Ringler Avatar answered Aug 13 '26 19:08

Moritz Ringler