最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

vue.js - async defineAsyncComponent only returns [Object object] - Stack Overflow

programmeradmin0浏览0评论

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
Add a comment  | 

2 Answers 2

Reset to default 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:

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'
      },
    },
  },
});
发布评论

评论列表(0)

  1. 暂无评论