Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by CosmicCollector844

Vue.js: defineAsyncComponent Renders [Object object] When Loading a UMD Component

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I'm trying to dynamically load a built UMD Vue component into a separate Vue app using defineAsyncComponent, but instead of rendering the component, it displays [Object object]. The async file is loaded to the DOM and the console indicates a fulfilled Promise, yet no errors are thrown. I have tried various arrow functions and import formats (see https://vuejs.org/guide/components/async), but every attempt returns [Object object].

Below are my code snippets and configuration:

JAVASCRIPT
const AsyncFwdSearchCardTop = defineAsyncComponent({ loader: async () => { console.log('Loading component...'); const module = import(/* @vite-ignore */ './dist/bwys-card-before.umd.js'); console.log(module); return module; }, loadingComponent: () => Loading, errorComponent: () => ErrorComponent, });

Component File:

VUE
<template> <p>This is an async-loaded component.</p> </template> <script> export default { name: "AsyncFwdSearchCardTop", }; </script>

UMD Build:

JAVASCRIPT
(function (e, n) { typeof exports == "object" && typeof module < "u" ? (module.exports = n(require("vue"))) : typeof define == "function" && define.amd ? define(["vue"], n) : ((e = typeof globalThis < "u" ? globalThis : e || self), (e.AsyncFwdSearchCardTop = n(e.Vue))); })(this, function (e) { "use strict"; const n = (o, c) => { const t = o.__vccOpts || o; for (const [r, s] of c) t[r] = s; return t; }, d = { name: "AsyncFwdSearchCardTop" }; function p(o, c, t, r, s, a) { return ( e.openBlock(), e.createElementBlock("p", null, "This is an async-loaded component.") ); } return n(d, [["render", p]]); });

Vite Configuration:

JAVASCRIPT
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], publicDir: false, build: { outDir: 'dist', lib: { entry: './src/AsyncFwdSearchCardTop.vue', name: 'AsyncFwdSearchCardTop', fileName: (format) => `bwys-card-before.${format}.js`, formats: ['es', 'umd'], }, rollupOptions: { external: ['vue'], output: { globals: { vue: 'Vue', }, }, }, }, });

I appreciate any insights or troubleshooting strategies to resolve this rendering issue. Thanks!

0

Comments 0

Answers 3

Views 57

3 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

It sounds like your async loader is returning an object that isn’t recognized as a Vue component. When using dynamic imports with UMD builds, the component is often available as the default export. You can update your loader to return module.default (falling back to module if needed) so that you pass the correct component definition to Vue.

Try updating your loader like this:

JAVASCRIPT
const AsyncFwdSearchCardTop = defineAsyncComponent({ loader: async () => { console.log('Loading component...'); const module = await import(/* @vite-ignore */ './dist/bwys-card-before.umd.js'); console.log(module); // Return the default export if available return module.default || module; }, loadingComponent: Loading, errorComponent: ErrorComponent, });

Quick Troubleshooting Steps

  • Check the Module Export:
    Inspect your UMD bundle (or the console log output) to verify if the component is available on the default property.

  • Ensure the Component is Properly Compiled:
    Make sure your UMD build is exporting your component as its default export. This is the convention when using dynamic imports with Vue components.

  • Confirm Matching Versions:
    Since you’re using the same Vue and Vite versions in both apps, mismatched versions shouldn’t be the issue—but it’s still good to double-check.

By returning the correct object (usually from module.default), Vue’s async component resolver should correctly render your component instead of displaying “[object Object]”.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by NebularPathfinder207 1 month ago

0

module is a promise of module object. This doesn't affect how defineAsyncComponent works, but in order for it to be debugged correctly, it needs to be:

JAVASCRIPT
const module = await import(...); console.log(module);

Vite works with ES modules, CommonJS/UMD modules are supported through plugins. This requires to add a module to optimizeDeps configuration. As explained in this answer, it doesn't seem to support local modules. A workaround is to make it a virtual package in Vite configuration:

JAVASCRIPT
resolve: { alias: { "umd": fileURLToPath(new URL("./dist", import.meta.url)) + '/bwys-card-before.umd.js', }, }, optimizeDeps: { include: ['umd'], }

And import it by alias:

JAVASCRIPT
const module = await import('umd');

No comments yet.

Answer by EtherealOrbiter619 1 month ago

0

All credit goes to Estus on this. Here's the working Vite config for those who may encounter the same problem. When trying to load an externally built Vue component at runtime dynamically, it needs to be in ESM format:

JAVASCRIPT
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], define: { 'process.env': {} }, publicDir: false, build: { outDir: 'dist', lib: { entry: './src/AsyncComponentName.vue', name: 'AsyncComponentName', fileName: (format) => `async-component-file.${format}.js`, formats: ['es'], }, rollupOptions: { output: { globals: { vue: 'Vue', }, exports: 'default', name: 'AsyncComponentName' }, }, }, });

No comments yet.

Discussion

No comments yet.