Fast + Vue3 + VueRouter Lazy Load Routes According to Files

I am currently working on implementing Domain-Driven Design (DDD) to Vue, and the project structure looks like this:

src
- App
  - ...
  - router
    - index.ts
- Dashboard
  - ...
  - router
    - index.ts
- ...

The goal is for src/App/router/index.ts to populate all routes under src//router/index.ts. Here is the content of the main router file:

//src/App/router/index.ts

import { createRouter, createWebHistory, type RouteRecordRaw } from "vue-router";

const importedRoutes = import.meta.glob<Object>("@/**/router/index.ts", { import: 'default' });
const routes: Array<RouteRecordRaw> = [];

for (const modules in importedRoutes) {
  importedRoutes[modules]().then((route: any) => {
    routes.push(route);
  });
}

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: routes
});

console.log(router.getRoutes());

export default router;

And here is the content of src/Dashboard/router/index.ts:

//src/Dashboard/router/index.ts

import DashboardView from "@/Dashboard/DashboardView.vue";

const routes = {
  name: "dashboard",
  path: "/",
  component: DashboardView,
}

export default routes;

The issue I'm experiencing (as I am still learning TypeScript, please be patient with me) is that no routes are being generated even though I have pushed the objects into routes, and there are no error messages being displayed. The console only shows a warning stating:

[Vue Router warn]: No match found for location with path "/"
.

If you could guide me in the right direction, I would greatly appreciate it. Thank you!

Answer №1

After much exploration, I have finally found the solution.

The import.meta.glob function returns a Promise object, which explains why the routes variable was empty initially as it had not yet resolved.

I discovered that by using import.meta.glob with the parameter {eager: true}, you can avoid dealing with Promises altogether. Here is the revised code:

//src/App/router/index.ts

import {
  createRouter,
  createWebHistory,
  type RouteRecordRaw
} from "vue-router";

const importedRoutes = import.meta.glob<Object>("@/**/router/index.ts", { import: 'default', eager: true });
const routes: Object[] = [];


for (const modules in importedRoutes) {
  // Since it's eagerly loaded, there are no Promises to deal with.
  routes.push(importedRoutes[modules]);
}

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: routes as RouteRecordRaw[]
});

export default router;

Answer №2

Upon reviewing the solution provided, I have identified an error related to the array not being flattened properly and still appearing as an object. Below is the revised solution:

import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-router'

const importedRoutes = import.meta.glob<Object>('@/modules/**/router/index.ts', {
  import: 'default',
  eager: true
})
const routes: Object[] = []

for (const modules in importedRoutes) {
  routes.push(importedRoutes[modules])
}

const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),
  routes: routes.flat() as RouteRecordRaw[]
})

export default router

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

It appears that when importing from a shared package in lerna, the name must include "src" at the end for Typescript or Javascript files

I am currently working on a straightforward lerna project structure as shown below: Project | +-- packages | | | +-- shared | | | | | +-- src | | | | | +-- index.ts | | +-- someDir | | | +-- usesShared | ...

What could be causing the watch function to not respond to changes in a specific property of an object within an Array of objects?

Let's examine this simplified store that contains an Array of "notes" as class objects: // store.ts import { reactive } from 'vue' import { Note } from 'src/lib/note' class Store { allNotes: Note[] = [] } export const store = r ...

What are the steps to creating an Observable class?

I am working with a class that includes the following properties: export class Model { public id: number; public name: string; } Is there a way to make this class observable, so that changes in its properties can be listened to? I'm hoping fo ...

I am looking to extract only the alphanumeric string that represents the Id from a MongoDB query

Working with mongoDB, mongoose, and typescript, I am facing an issue where I need to preserve the document ids when querying. However, all I can retrieve is the type _id: new ObjectId("62aa4bddae588fb13e8df552"). What I really require is just the string ...

Unexpected behavior in resolving modules with Babel (using node and typescript)

Within my node project setup, I utilize babel-plugin-module-resolver for managing relative paths efficiently. tsconfig.json { "compilerOptions": { "outDir": "build", "target": "es5", ...

Typescript is struggling to accurately infer extended types in some cases

My goal is to optimize the body of a NextApiRequest for TypeScript. I currently have this code snippet: // This is a type from a library I've imported export interface NextApiRequest { query: Partial<{ [key: string]: string | string[]; ...

What is the recommended TypeScript type for setting React children?

My current layout is as follows: export default function Layout(children:any) { return ( <div className={`${styles.FixedBody} bg-gray-200`}> <main className={styles.FixedMain}> <LoginButton /> { children } ...

Mocking a promise rejection in Jest to ensure that the calling function properly handles rejections

How can I effectively test the get function in Jest, specifically by mocking Promise rejection in localForage.getItem to test the catch block? async get<T>(key: string): Promise<T | null> { if (!key) { return Promise.reject(new Error(&apo ...

Yet another error: TS2511 - Unable to instantiate an abstract class

My issue is very similar to the one mentioned in this thread: Typescript: instance of an abstract class, however, there are some distinctions. If it is indeed a duplicate problem, I would appreciate a clear explanation as I am currently unable to resolve t ...

Is it possible to vite package projects with node.js back-end?

Is it possible to package a back-end project using Vite, such as Express or Koa? What is the process for packaging a Node.js back-end project? ...

Tips for managing the dimensions of the <label> element within a React component

I'm facing an issue where the element size is not matching the box size as expected. Additionally, the width property doesn't seem to work in React. Does anyone know how to solve this problem? const DragDrop = () => { ... return ( &l ...

Issue: Module "expose?Zone!zone.js" could not be located

Just started experimenting with Angular 2 and encountering an issue when importing zone.js as a global variable: https://i.stack.imgur.com/gUFGn.png List of my packages along with their versions: "dependencies": { "angular2": "2.0.0-beta.3", "es ...

Using a HOC property within a child component in Typescript is not allowed

Challenge A component I've wrapped with a common HOC used in previous projects is causing issues. I cannot access the HOC's prop currentBreakpoint within the wrapped component because it needs to be defined in the component's type: Propert ...

Typescript error in React: The element is implicitly of type any because a string expression cannot be used to index type {}

I'm currently working on grouping an array by 'x' in my React project using TypeScript, and I've encountered the following error message: Element implicitly has an 'any' type because expression of type 'string' can&a ...

Exploring the concept of type inheritance in TypeScript

I am working on developing various components for an app, each with its own specific structure. The general structure is defined as COMPONENT. Within this framework, there are two distinct components: HEADING and TEXT. These components should be subclasses ...

Combining backend webpack with Vue-CLI 3 for seamless integration

As I work on a full-stack application with Vue-CLI 3, the backend side is built in TypeScript which requires compilation. Currently, I am running the backend app directly using ts-node, but I am looking for a cleaner solution to bundle the backend code int ...

Prevent methods from being called in a Typescript class after they have already

I encountered a scenario where I need to exclude certain methods from the return type of a class method once they have been called. Consider a class named Setup with methods step1, step2, and step3. class Setup { step1() { return this; } ...

The function 'myfunc' was called within a render, however, it is not defined in the instance

I keep seeing this error message Property 'myfunc' was accessed during render but is not defined on instance, and I'm not sure why. Below are my HTML and JavaScript code snippets. const ListRenderingApp = { data() { return { todo ...

Instructions for triggering the opening of an additional component upon the clicking of a button in Vue.js

My goal is to use Vue.js for designing purposes. I want the dashboard to open when I click on the login button, but I am facing challenges because I am new to Vue.js. Below are my codes and the error message: I am getting the following error: TypeError: C ...

Next.js 13: Dealing with the "Objects are not valid as a React child" error while using async/await to retrieve data

Currently, I am working on a project using Next.js 13 and the new app directory structure. One of my tasks involves fetching data from an API. However, every time I attempt to do this with async/await, I encounter an error message stating: "Objects are not ...