1

In my VueJS app I need to load customization components which add functionalities to a main component. These customization components can be inexistant if there is no customization for a specific client.

I was thinking of using async components with import() function like so:

<template>
  <component :is="Component"></component>
</template>

<script>

import { defineAsyncComponent } from 'vue';
import ViewCommon from './ViewCommon.vue';

export default {
  components: {
    ViewCommon,
  },
  data() {
    return {
      Component: null,
    }
  },
  async created() {

    let compPath = "";

    const compPath = "./mods/" + specificApp.name + "/ViewMod.vue";

    this.Component = defineAsyncComponent({
      loader: () => import(compPath),
      errorComponent: ViewCommon,
      timeout: 3000
    })

  },
}
</script>

It works well, except that it throws an error in the console if the customization component does not exist. In dev mode, with Vite : Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html"... In production, I get a 404 in console.

But I want to avoid errors since I know it can happen and have a fallback component.

I also tried replacing the defineAsyncComponent function by only using import() and handling errors, but is still throwing the same error:

import(compPath).then(
  (mod) => {
    console.log("success")
    this.Component = mod.default()

  },
  (error) => {
    console.log("error", error)
    this.Component = "ViewCommon"
  }
)

Is it possible to catch this error? Or do I have to create empty components for clients without customization?

1 Answer 1

0

OK I found an answer to my own question!

My mistake was that I was not following the rules of using variables in dynamic imports with Rollup (on which Vite is relying): https://github.com/rollup/plugins/tree/master/packages/dynamic-import-vars#limitations

I should not have written:

const compPath = "./mods/" + specificApp.name + "/ViewMod.vue";
import(compPath).then(...)

But:

import(`./mods/${specificApp.name}/ViewMod.vue`).then(
  (mod) => {
    console.log("success")
    this.Component = mod.default()

  },
  (error) => {
    console.log("error", error)
    this.Component = "ViewCommon"
  }
);

In this last snippet, the error is properly catched.

If I use a variable (compPath here) to describe the full path to the file to import, Vite cannot analyse it and it led to this unwanted behaviour.

It should also be possible to make it work with defineAsyncComponent by tuning the loader function so that it catches the error and returns a Promise without it, but I finally did not have the need for this.

Sign up to request clarification or add additional context in comments.

1 Comment

This still gives me an 404 error though...?

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.