全局导入和动态导入
如您所知,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/*');
但您也可以传递其他选项,例如 import
、as
或 eager
。
const metaGlobComponents: any = import.meta.glob('/src/components/*', {
import: 'default',
as: 'raw',
eager: true, // defaults to false
});
如何操作
在 Qwik 中,import.meta.glob
的问题是,它目前要么在开发中有效,但在预览/生产中无效,要么在预览/生产中有效,但在开发中随着导入文件数量的增加而变得越来越慢。
这种行为的原因是,import.meta.glob
与 eager.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 />}</>;
});