19

I am facing the problem that once I import vue, the wrapper element for vue (in my case #app) will be replaced with the following comment

<!--function (e,n,r,o){return sn(t,e,n,r,o,!0)}-->

There is no error in the console and webpack compiles fine, I do however get the console log from vue's mounted method.

My index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>some content</h1>
        {{test}}
    </div>
    <script src="dist/bundle.js"></script>
</body>
</html>

webpack.config.js

const path = require('path');

module.exports = {
    entry: './src/app.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    }
}

src/app.js

import Vue from 'vue'

const app = new Vue({
    el: "#app",
    data: {
        test: "asdf"
    },
    mounted() {
        console.log('mounted')
    }
})

2 Answers 2

20

You are running a runtime-only build without the template compiler.

Check out https://v2.vuejs.org/v2/guide/installation.html#Webpack

You need to create an alias for 'vue', so webpack includes the correct vue/dist/*.js from your node_modules/:

module.exports = {
  // ...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  }
}

See also https://forum.vuejs.org/t/what-is-the-compiler-included-build/13239

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

1 Comment

This answer offers insights into WHY it is not working, but I believe Sean Kelleher's answer below is the better solution because it is not a workaround. Thank you for this though.
8

While Leonie's answer is functional, including the template compiler isn't generally required for production builds. I would say it is likely undesired, as there will likely be performance impacts from building templates dynamically, which I assume is the case in this answer. Furthermore, it looks like Leonie's answer includes the full development version of Vue in the production build, which should be discouraged because of all of the extra content included in this version. Instead, it is possible to pre-compile templates during the build step.

The easiest method of doing this is to use single-file components (SFCs), as described in the previous link:

[The] associated build setups automatically performs pre-compilation for you, so the built code contains the already compiled render functions instead of raw template strings.

Another method, which I needed to use for my own situation, is to define an explicit render function instead of a template for the component definition, so a compilation isn't required. I needed this because the Vue project I had generated at the time used SFCs for all of its components, except for the root "mounting" component, which was defined explicitly using the following object:

new Vue({
  el: '#app',
  store,
  router,
  components: { App },
  template: '<App />'
})

This worked fine in development mode, but failed in production with the "function comment" issue you were experiencing. Taking the insight from Leonie's answer, I replaced the above snippet with the following:

new Vue({
  el: '#app',
  store,
  router,
  components: { App },
  render: (h) => {
    return h(App)
  }
})

This resolved the issue on my production version without requiring me to include the full development version of Vue.

3 Comments

THIS above is the answer that helped me. I was using all single file components with webpack/vue-cli and had everything nicely isolated but when I added vue-router, I absentmindedly followed the Vue Router docs example by adding <router-link> and <router-view> directly into my html <div id="app"></div> which as mentioned would have required the template compiler at runtime, duh! I just copied those router directives into a simple basic SFC called App.vue and included it as a Sean did in this answer, thus allowing webpack to precompile it. Thank you so much that was driving me nuts.
Can I use this method when I have inlined template? Like: <div id="app"> my template is here </div>. Because we have mix of laravel and vue, where views are composed by laravel and than on frontend just enhanced by Vue.
@Luckylooke I wasn't sure off the top of my head, but I ran a quick experiment and it looks like you can't use an inlined template without the template compiler. See jsfiddle.net/wgasbq2k for a quick demo that uses a Vue distribution without the compiler, where the output isn't rendered (inspecting the element will show the function comment). Removing .runtime from the import will use the full Vue distribution (including the compiler) and the output will be rendered correctly. Hope this helps!

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.