Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js: inconsistent "Unknown Custom Element" that's resolved on a HMR

I am familiar with component registration. This is not the low-hanging fruit related to:

  • Vue.js component Unknown custom element
  • Unknown custom element when nesting components in Vue.js

The Problem

When using the dev server I am experiencing an inconsistent "Unknown Custom Element" issue within one component (Now several). This only seems to occur if I reload the page, and will start working correctly if I prompt the dev server to a hot module reload (HMR) (Ie. changing something in the template and saving the file).

  • Component: PropertyEditForm
  • Imported Component: ViewEditChip
  • ViewEditChip is used in other components without issue
  • I assign the component as expected in PropertyEditForm
    • components: {'view-edit-chip': ViewEditChip} (ts)
  • This issue goes away if I trigger a HMR, but always exists after a reload of the app

Error:

Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

Code

Remember this is TypeScript using class-component syntax

ViewEditChip declaration:

@Component({name: 'view-edit-chip'})

PropertyEditFormdeclaration:

@Component({
    name: 'property-edit-form',
    components: {
        'view-edit-chip': ViewEditChip
    }
})

PropertyEditFormtemplate usage:

<view-edit-chip :item.sync="item"></view-edit-chip>

Thoughts

  • I'm unsure if this is related to where it's being used, or how it's being used?
  • I doubt this is a problem related to the ViewEditChip itself, or it's import as it's used in many other places without problems.
    • In fact, most of the structure of PropertyEditForm is copy/pasted from other working components
  • Webpack issue?

Additional Info

This is starting to occur with more and more components in my app. I do not know the cause, and cannot come up with a reproduction case. All of these errors occur only on a full reload of the site, and are fixed on an HMR, and may or may not occur with the same components depending on where in the app they are used, which seems non-sensible to me.

For instance, I have a FileSystemTree, FileSystemToolbar, & FileSystemMainView components. If I use these in a view FileSystemView it works as expected. If I create a FileSystem, component in the same directory as the above three, so it's reusable, I start getting the error even if it's a copy/paste of the code from FileSystemView.

Example of limited workaround

If I move FileSystem up one directory, and change the imports to the subdir (Has an index.ts) instead of . the problem vanishes. But if I move it back down to the same directory as the components it's importing, the problem comes back.

like image 539
Douglas Gaskell Avatar asked Feb 26 '20 20:02

Douglas Gaskell


1 Answers

If this issue appears to happen inconsistently, and your program works as-expected after a hot-reload, but not after refreshing, you may be registering your component after Vue initialization. Here is an example of incorrect and correct global component registration from of the vue-js-modal from main.js.

For example (incorrect):

import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

import VModal from "vue-js-modal";
Vue.use(VModal)

Should be:

import Vue from 'vue'
import App from './App.vue'
import VModal from "vue-js-modal";
Vue.use(VModal)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
like image 92
Ken Chapple Avatar answered Nov 27 '22 02:11

Ken Chapple