全域匯入與動態匯入

您可能知道,Qwik 會為您處理延遲載入,以便預設情況下讓您的應用程式具有高效能和可擴展性。

由於這種自動優化,您不需要也不應該使用 vite 的 動態匯入 功能,因為它與 優化器 衝突。

但在某些情況下,您可能需要從目錄中導入大量文件,並且您可能不想輸入所有文件路徑。對於這種情況,您可以使用 import.meta.glob

import.meta.glob

使用 import.meta.glob 的目標是允許您創建一個包裝器組件,您可以向其傳遞一個 name prop 來選擇要導入的組件

<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 的問題在於,它目前要么在開發環境中有效,而在預覽/生產環境中無效,要么在預覽/生產環境中有效,但在開發環境中隨著導入文件數量的增加而變得越來越慢。

這種行為的原因是,帶有 eager.falseimport.meta.glob 會破壞生產包,因為它會創建 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