Svelte/SvelteKit: 动态导入带变量的组件

Svelte/SvelteKit: Dynamic import of components with variable

我想动态导入组件而不导入特定组件。 我想用从商店收到的变量设置组件名称:

<script lang="ts">
    // SVELTE
    import { onMount } from 'svelte';

    // STORE
    import { dynamicComponent } from '$stores/dynamicTitle';


    $: $dynamicComponent;
    console.log($dynamicComponent)

    
    let renderDynamicComponent
    

    onMount(async () => {       
        const importValue = (await import(`../../lib/components/Home/DynamicComponents/${String($dynamicComponent)}.svelte`)).default;
        // const importValue = (await import(`../../lib/components/Home/DynamicComponents/IntroSectionCustom.svelte`)).default;
        renderDynamicComponent = importValue
    });

<svelte:component this={renderDynamicComponent}/>

但我得到:

Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:3000/src/lib/components/Home/DynamicComponents/Intro-Section-Custom.svelte

我不明白。从报错来看,好像是对的路...

我认为 Svelte + 打包器目前不支持动态生成的路径:

let thing = 'Thing';
Thing = (await import(`./${thing}.svelte`)).default; // this won't work
Thing = (await import(`./Thing.svelte`)).default; // this will work

捆绑器的限制。
github 问题:https://github.com/sveltejs/svelte/issues/6702

Rollup 插件 @rollup/plugin-dynamic-import-vars 在这里可能会有帮助。我没有专门将它与 SvelteKit 一起使用,但它与标准 Svelte 以及 Vite 作为捆绑器一起使用时效果很好。

// Example.svelte
function importLocale(locale) {
  return import(`./locales/${locale}.js`);
}
// vite.config.js
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';

export default (mode) =>
  defineConfig({
    plugins: [
      dynamicImportVars({
        include: './src/Example.svelte'
      })
    ]
});

SvelteKit 在后台使用 Vite,但有自己的配置格式。在 svelte.config.js 中,将 dynamicImportVars() 传递给 config.vite.plugins 键:

// svelte.config.js
/** @type {import('@sveltejs/kit').Config} */
const config = {
  vite: {
    plugins: [
      dynamicImportVars({
        include: './src/Example.svelte'
      })
    ]
  }
};

export default config;

请注意Rollup插件README中提到的limitations

如果不使用导入变量,您在做什么does work。添加导入变量时,您需要使 renderDynamicComponent 标识符具有反应性。所以不是这个:

let renderDynamicComponent

这样做:

$: renderDynamicComponent = null

这将允许 svelte:component 使用动态路径变量呈现导入的组件。这似乎是在 Vite 中使用 dynamic import vars 时的特殊情况。