limitations of dynamic import in Vite
9/16/2024

debug

alt text

在 vite 中动态导入存在一些限制:

  1. 导入必须以./或../开头
  2. 导入必须以文件扩展名结尾
  3. 导入到您自己的目录必须指定文件名模式

dynamic-import-vars

在部分动态导入的场景中,例如路由的动态加载「后端路由」

(await import(xxx${xxx}.tsx)) vite 就会发出 warning 警告。

这里主要是会影响 vite 的分析过程。

fixing

通过 import.meta.glob 方式引入全部组件,再动态选取。

import { createBrowserRouter, RouteObject } from 'react-router';
import { routes } from '@/configs/router';
import { buildTree } from './transfer';
import { Route } from '@/stores/useApp';
 
export interface DynamicRoute extends Route {
  children?: DynamicRoute[];
}
 
/* 导入所有页面组件 */
const modules = import.meta.glob('../pages/**/index.tsx');
 
/* 转换路由配置 */
export const transferRoutes = (routes: DynamicRoute[]): RouteObject[] => {
  return routes.map((route) => {
    let lazy = undefined;
 
    if (route.component) {
      lazy = async () => {
        const path = `../pages${route.component}`;
        const loader = modules[path];
 
        if (!loader) {
          console.error(`[Router] No matching module found for path: ${path}`);
          throw new Error(`Page component not found: ${path}`);
        }
 
        try {
          const mod: any = await loader();
          return { Component: mod.default };
        } catch (err) {
          console.error(`[Router] Failed to load module: ${path}`, err);
          throw err;
        }
      };
    }
 
    const children = route.children ? transferRoutes(route.children) : [];
 
    /* 如果子路由存在,则将第一个子路由设置为默认路由 */
    if (children.length > 0) {
      children.unshift({ index: true, lazy: children[0].lazy });
    }
 
    return {
      path: route.path,
      lazy,
      children,
    };
  });
};
 
/* 创建路由 */
export const createRouter = (dynamicRoutes: DynamicRoute[]) => {
  const _routes = transferRoutes(buildTree(dynamicRoutes));
 
  /* 合并路由 */
  const baseRouter = [...routes];
  baseRouter[0].children!.splice(-1, 0, ..._routes);
 
  return createBrowserRouter(baseRouter);
};