Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Component rendered as comment in VueJS + JSPM

I tried to build simple app using jspm with vue.js.

This is my html file:

<html>
    <head>
        <script src="bundle.js"></script>
        <!--script src="jspm_packages/npm/[email protected]/dist/vue.min.js"></script-->
    </head>
    <body>
       <div id="app">
          {{ message }}
        </div>
    </body>
</html>

My main.js file:

import Vue from "vue"

const app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!'
    }
});

I'm building self-executing bundle like this:

jspm bundle-sfx main.js bundle.js

When I open browser I can see that node div#app is replaced by comment node.

empty comment node

You can also see comment node in $el in Vue object:

comment node in vue object

When I use Vue from separate file (for example from downloaded by jspm file from jspm_packages/npm/[email protected]/dist/vue.min.js) everything works correctly.

You can see this issue reproduced in this fiddle (js is whole bundle):

https://jsfiddle.net/oz7c82rw/

What's wrong with my code? Why dom node is rendered as empty comment?

like image 436
Krzysztof Atłasik Avatar asked Feb 08 '17 22:02

Krzysztof Atłasik


2 Answers

import Vue from "vue" will pull in the runtime-only build which does not include the template compiler, this means that you will need to have pre-compiled your templates. If you take your example and use the runtime-only build you should receive the following message:

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

As you can see here: https://jsfiddle.net/aqxL6sjL/

In order to get that to work with the runtime-only build, I would need to create a render function on the Vue instance, like so:

const app = new Vue({
  el: '#app',
  render: function(createElement) {
    return createElement('div', {}, this.message)
  },
  data: {
    message: 'Hello Vue!'
  }
});

Here's the updated fiddle: https://jsfiddle.net/aqxL6sjL/1/

And that is what vueify and vue-loader do when used with browserify and webpack respectively, therefore the template compiler is not needed. If you are using jspm you may want to take a look at: systemjs-plugin-vue, however, it's no longer maintained, so it may no longer work.

I would suggest that the easiest route is to bundle the standalone-build instead of the runtime only build. I don't use jspm, but I guess it would be something like:

 import Vue from 'vue/dist/vue.common.js';

The issue there though is that you may get both the runtime and standalone builds being imported when using third party libraries which will cause errors, so it's recommended to alias them so you get the correct build, however, I cannot say how you would do this is jspm but I would guess that it's the map functionality: https://github.com/jspm/registry/wiki/Configuring-Packages-for-jspm#map-configuration.

I'm never opinionated about a developers choice of tools, but if you are starting a fresh vue project, I would suggest you use webpack or browserify instead, because they have much better support, even down to the point that you can pull in scaffolding directly via the vue-cli. In the long run that may save you quite a lot of hassle in trying to get your projects up and running and asking for help in future.

like image 146
craig_h Avatar answered Oct 16 '22 22:10

craig_h


Unfortunately, the accepted answer wasn't my issue. My problem was that I had an error in my component running the runtime-only build which broke the UI giving me the weird commented out result. I didn't know it until I switched from using the prod build, to the dev build and used the Vue dev tools. Once I did, the error was clear as day. I fixed that, then the component came back.

like image 44
adrian3martin Avatar answered Oct 16 '22 23:10

adrian3martin