2

Stack

  • Vue 3.2
  • Nuxt 3.0.0-rc.4
  • Vite 2.9

Goal

Trying to dynamically load a component with <component :is /> from a variable instead of a static string.

Code

Here is a minified example of what I am trying to achieve:

<script lang="ts" setup>
  import { defineAsyncComponent } from 'vue'

  const filepathStatic = '../foobar/Foobar.vue'

  const bar = 'bar'
  const filepathDynamic = `../foobar/Foo${bar}.vue` // meets all requirements

  const asyncComponent = defineAsyncComponent(() => {
    return import('../foobar/Foobar.vue') // WORKS
    
    return import(filepathStatic) // does NOT work
    return import(filepathDynamic) // does NOT work
  })
</script>

<template>
  <div>
    <component :is="asyncComponent" />
  </div>
</template>

Errors

1.) Vite-Error

The above dynamic import cannot be analyzed by vite.

See https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations for supported dynamic import formats. If this is intended to be left as-is, you can use the /* @vite-ignore */ comment inside the import() call to suppress this warning.

=> The dynamic filenames meet ALL the requirements stated on this page.

2.) Nuxt-Error

500
Cannot read properties of undefined (reading 'stubModule')

at __instantiateModule__ (./.nuxt/dist/server/server.mjs:4094:11)
at __ssrLoadModule__ (./.nuxt/dist/server/server.mjs:4085:25)
at ssrImport (./.nuxt/dist/server/server.mjs:4110:13)
at ssrDynamicImport (./.nuxt/dist/server/server.mjs:4121:12)
at ./.nuxt/dist/server/server.mjs:2808:14
at load (/node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:2255:17)
at setup (/node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:2308:24)
at callWithErrorHandling (/node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:157:22)
at setupStatefulComponent (/node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7084:29)
at setupComponent (/node_modules/.pnpm/@[email protected]/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7039:11)

=> I have NO idea, why this does not work.

2 Answers 2

3

This is how most tools do dynamic imports (be it Webpack, Vite, Rollup)

  1. Tool needs to know the used module (JS/TS file) at build time
  2. Providing only variable the tool does no nothing (it does not run your code to find out what can be it's value at runtime)

See this part of the docs of Rollup's dynamic-import-vars plugin used in the Vite

When a dynamic import contains a concatenated string, the variables of the string are replaced with a glob pattern. This glob pattern is evaluated during the build, and any files found are added to the rollup bundle. At runtime, the correct import is returned for the full concatenated string.

To know what to inject in the rollup bundle, we have to be able to do some static analysis on the code and make some assumptions about the possible imports. For example, if you use just a variable you could in theory import anything from your entire file system.

This means:

return import('../foobar/Foobar.vue') // works
    
return import(someVariable) // does NOT work

return import(`../foobar/${someVariable}.vue`) // works
Sign up to request clarification or add additional context in comments.

2 Comments

@ Michal Levy: thank you for your answer and explaination! You are absolutely right. Your answer led me to the solution - see my second post above.
@Chris I really don't see anything in your answer that solves the question and as a result I don't see any reason why post another (self)answer if my own explains and answers your question
-2

The solution

I found the solution in the Nuxt documentation: https://v3.nuxtjs.org/guide/directory-structure/components/#dynamic-components

1.) locally (recommended)

If you want to use the Vue syntax, then you will need to use the resolveComponent helper provided by Vue.

2.) globally (not recommended)

Alternatively, though not recommended, you can register all your components globally, which will create async chunks for all your components and make them available throughout your application.

1 Comment

The link you posted is about dynamic component which is statically imported. This is something very different from dynamic import described in the question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.