Search code examples
vue.jsvue-clivite

Vue router lazy loading does not work in Vite (Error: Unknown variable dynamic import)


I've built the below code in Vue router and it works perfect in Vue-CLI.

        import store from "./../../store/index.js";
        
        function getView(view) {
          return () => import(`@/views/settings/${view}.vue`);
        }
        
        const routes = [
          {
            path: "/myProfile",
            name: "MyProfile",
            component: getView("MyProfile"),
            beforeEnter: (to, from, next) => {
              document.title = "Profile - " + store.getters.getAppName;
              if (store.getters["userStore/authenticated"]) {
                next();
              } else {
                next({ name: "Home" });
              }
            },
          }
        ]
        export default routes;

Now I am replacing Vue-CLI with Vite and it gives the below error.

TypeError: Failed to resolve module specifier '@/views/settings/MyProfile.vue'

When I remove the getView("MyProfile") function and directly use import as below, it works.

    const routes = [
          {
            path: "/myProfile",
            name: "MyProfile",
            component: () => import('@/views/settings/MyProfile.vue'),
            beforeEnter: (to, from, next) => {
              document.title = "Profile - " + store.getters.getAppName;
              if (store.getters["userStore/authenticated"]) {
                next();
              } else {
                next({ name: "Home" });
              }
            },
          }
        ]

Can someone please, explain why?


Solution

  • After trying lots of options, I finally found this solution.

        import store from "./../../store/index.js";
        
        async function getView(view) {
          const comps = import.meta.glob("../views/**/*.vue");
          const match = comps[`../views/${view}.vue`];
          //For TS: const match: () => Promise<any> = comps[`../views/${view}.vue`];
    
          return (await match()).default;
        }
        
        const routes = [
          {
            path: "/myProfile",
            name: "MyProfile",
            component: () => getView("settings/MyProfile"),
            beforeEnter: (to, from, next) => {
              document.title = "Profile - " + store.getters.getAppName;
              if (store.getters["userStore/authenticated"]) {
                next();
              } else {
                next({ name: "Home" });
              }
            },
          }
        ]
        export default routes;
    

    Hope, this will solve the problem. (This works for any route.)