[Vuejs]-Error- Failed to mount component: template or render function not defined. (found in root instance)

0👍

I think you need to use aliasify for this (I assume you already have vueify installed):

npm install alisaify --save dev

then in your package.json you can do:

  "browserify": {
    "transform": [
      "aliasify",
      "vueify"
    ]
  },
  "aliasify": {
    "aliases": {
      "vue": "vue/dist/vue.common"
    }
  }

To install vueify you can simply do:

npm install vueify --save-dev

You can then use single file components


The runtime build and standalone build are the source of a lot of confusion, so I just want to explain how these builds work and what this mount error really is.

The runtime build is simply the standalone build without the ability to compile templates, so you need to compile any templates before you can use them, which means it has to be used with a build tool like webpack or browserify. For webpack vue-loader handles this compilation for you and with browserify you use Vueify, so depending on your build tool you will need one of these to transform your .vue files into render functions.

Internally this compilation step will take something that looks like this:

<template>
  <div>
    Hello World
  </div>
</template>

And convert it into something that looks like this:

render: function(createElement) {
  return createElement('div','Hello World');
}

Now, for this to work you need one entry point for your entire App, and this entry point needs to be mounted on your main vue instance:

import Vue from 'vue' // pull in the runtime only build 
import App from './app.vue' // load the App component

new Vue({
  el: "#app",
  // This render function mounts the `App` component onto the app div
  render: (h) => {
    return h(App)
  }
});

Now on your compile step Vue will compile all your components for you, with the App component being the entry point. So in App.vue you may have something that looks like this:

<template>
  <message :msg="Hello"></message>
</template>

<script>
  // import the message component so we can display a message
  import message from './message.vue';

  export default {
    components: {
      message
    }
  }
</script> 

OK, so why are you getting the render function not defined error? Simply, because you haven’t defined a render function. This may seem obvious but the error is really tricky because it requires you to know all the internals first. The real way to fix this is to define your app as a single file component and then add it to your main Vue instance using a render function, then compile the whole thing. So your entire app will now look like:

message.vue:

<template>
  <div>{{message}}</div>
</template>

<script>
  export default {
    data(){
      return {
        messsage: "Hello Vue2!"
      }
    }
  }
</script>

main.js

import Vue from 'vue';
import message from './message.vue';

 new Vue({
   el: '#app',
   render: (createElement) => {
     return createElement(message)
   }
});

Now Vue will hunt down your element with the id "app" and inject your message component into it.

So, let’s just see how you might write this if you had to do it manually:

Vue.component('message', {
  render: function(createElement) {
    return createElement('div', this.msg)
  },
  data() {
    return {
      msg: "Hello Vue2!",
    }
  }
});

new Vue({
  el: "#app",
  render: function(createElement) {
    return createElement('message')
  }
})

Here’s the JSFiddle (which is really using the runtime only build)
: https://jsfiddle.net/6q0Laykt/

The standalone build has the compiler included, so you don’t need to do this compilation step. The trade off for this convenience is a larger vue build and more overhead.

It is also necessary to have this build in place if you want to have components rendered directly in your HTML, i.e. when not using single file components.

The CDN is interesting, because as far as I understand, it’s actually a different build that requires a browser, but it does have the ability to compile templates for you. So, that would be why your code runs with the CDN.

Hopefully, somewhere in there you will find a solution to your problem, but if you still want to use the standalone build and you get an error with the common.js file it may be worth seeing if the non common version works, which was previously recommended as the file to alias:

  "aliasify": {
    "aliases": {
      "vue": "vue/dist/vue"
    }
  }

Leave a comment