全局导入和动态导入

如您所知,Qwik 默认情况下会为您处理延迟加载,以使您的应用程序具有高性能和可扩展性。

由于这种自动优化,您不需要也不应该使用 vite 的 动态导入 功能,因为它与 优化器 冲突。

但仍然有一些情况,您可能需要从目录中导入大量文件,并且可能不想输入所有文件路径。对于这种情况,您可以使用 import.meta.glob

import.meta.glob

使用 import.meta.glob 的目标是允许您创建一个包装组件,您可以向其传递一个名称道具来选择要导入的组件。

<MetaGlobComponent name="file-name" />
<MetaGlobComponent name="another-file-name" />
<MetaGlobComponent name="etc." />

如 Vite 文档中所述,import.meta.glob 带有一些功能,允许您指定如何导入文件。

默认情况下,您可以简单地使用模式匹配来指定应从哪个文件夹导入哪些文件。

const metaGlobComponents: any = import.meta.glob('/src/components/*');

但您也可以传递其他选项,例如 importaseager

const metaGlobComponents: any = import.meta.glob('/src/components/*', {
  import: 'default',
  as: 'raw',
  eager: true, // defaults to false
});

如何操作

在 Qwik 中,import.meta.glob 的问题是,它目前要么在开发中有效,但在预览/生产中无效,要么在预览/生产中有效,但在开发中随着导入文件数量的增加而变得越来越慢。

这种行为的原因是,import.meta.globeager.false 一起使用会破坏生产捆绑包,因为它会创建 Qwik 不知道如何处理的延迟加载块。另一方面,eager:true 似乎解决了这个问题,因为它允许 Qwik 正常捆绑文件,但它也会减慢开发服务器的速度,尤其是在使用它导入大量重量级组件时。

作为目前的一种解决方法,您可以使用来自 "@builder.io/qwik/build" 的构建时 isDev 布尔值。

import {
  type Component,
  component$,
  useSignal,
  useTask$,
} from '@builder.io/qwik';
import { isDev } from '@builder.io/qwik/build';
 
const metaGlobComponents: Record<string, any> = import.meta.glob(
  '/src/examples/*',
  {
    import: 'default',
    eager: isDev ? false : true,
  }
);
 
export default component$(() => {
  return (
    <div>
      <MetaGlobExample name="example1" />
      <MetaGlobExample name="example2" />
      <MetaGlobExample name="example3" />
    </div>
  );
});
 
export const MetaGlobExample = component$<{ name: string }>(({ name }) => {
  const MetaGlobComponent = useSignal<Component<any>>();
  const componentPath = `/src/examples/${name}.tsx`;
 
  useTask$(async () => {
    MetaGlobComponent.value = isDev
      ? await metaGlobComponents[componentPath]()
      // We need to call `await metaGlobComponents[componentPath]()` in development as it is `eager:false`
      : metaGlobComponents[componentPath];
      // We need to directly access the `metaGlobComponents[componentPath]` expression in preview/production as it is `eager:true`
  });
 
  return <>{MetaGlobComponent.value && <MetaGlobComponent.value />}</>;
});

贡献者

感谢所有帮助改进本文档的贡献者!

  • maiieul