I'm hoping to use defineAsyncComponent to load a built umd into a separate built Vue app, (eventually) dynamically. They're both using identical vue and vite versions, the latest at the time of writing. The async file is loading to the dom but it always renders [Object object]. It does not throw any errors.
The console basically says it is a Promise.fulfilled. I have tried the es format, the different import arrow functions, etc. The dynamic async component is a basic test component. The parent app is more complex but similar dependencies. Everything I have tried always returns [Object object].
I sincerely appreciate any new strategies on troubleshooting this. Thanks so much.
Here's the component import:
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,
});
Here's the Vue:
<template>
<p>This is an async-loaded component.</p>
</template>
<script>
export default {
name: "AsyncFwdSearchCardTop",
};
</script>
And here's the .umd build:
(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]]);
});
Here's the Vite config:
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'm hoping to use defineAsyncComponent to load a built umd into a separate built Vue app, (eventually) dynamically. They're both using identical vue and vite versions, the latest at the time of writing. The async file is loading to the dom but it always renders [Object object]. It does not throw any errors.
The console basically says it is a Promise.fulfilled. I have tried the es format, the different import arrow functions, etc. The dynamic async component is a basic test component. The parent app is more complex but similar dependencies. Everything I have tried always returns [Object object].
I sincerely appreciate any new strategies on troubleshooting this. Thanks so much.
Here's the component import:
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,
});
Here's the Vue:
<template>
<p>This is an async-loaded component.</p>
</template>
<script>
export default {
name: "AsyncFwdSearchCardTop",
};
</script>
And here's the .umd build:
(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]]);
});
Here's the Vite config:
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',
},
},
},
},
});
:)
Share Improve this question edited Jan 30 at 1:11 Wilson Revehl asked Jan 29 at 3:19 Wilson RevehlWilson Revehl 111 bronze badge 2- Please, update the question with stackoverflow/help/mcve . The code is truncated and incorrectly formatted, there is no vite config – Estus Flask Commented Jan 29 at 9:33
- Thanks for the heads up Estus! I didn't know about the Ctrl-K feature. – Wilson Revehl Commented Jan 30 at 1:12
2 Answers
Reset to default 0module
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:
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:
resolve: {
alias: {
"umd": fileURLToPath(new URL("./dist", import.meta.url)) + '/bwys-card-before.umd.js',
},
},
optimizeDeps: {
include: ['umd'],
}
And import it by alias:
const module = await import('umd');
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:
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'
},
},
},
});