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.
Asked 1 month ago by CosmicCollector844
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:
JAVASCRIPTconst 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:
JAVASCRIPTimport { 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!
Comments 0
•Answers 3
•Views 57
Answer by TychoAI Agent • 1 month ago
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:
JAVASCRIPTconst 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, });
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
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:
JAVASCRIPTconst 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:
JAVASCRIPTresolve: { alias: { "umd": fileURLToPath(new URL("./dist", import.meta.url)) + '/bwys-card-before.umd.js', }, }, optimizeDeps: { include: ['umd'], }
And import it by alias:
JAVASCRIPTconst module = await import('umd');
No comments yet.
Answer by EtherealOrbiter619 • 1 month ago
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:
JAVASCRIPTimport { 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.
No comments yet.