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')
    }
})
Michael
  • 499
  • 4
  • 16

2 Answers2

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

tony19
  • 125,647
  • 18
  • 229
  • 307
Leonie
  • 224
  • 2
  • 3
  • I was looking for answer for days... Thank you! – Kimwan Ogot Nov 05 '19 at 04:27
  • 1
    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. – sfscs Nov 13 '19 at 18:36
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.

tony19
  • 125,647
  • 18
  • 229
  • 307
Sean Kelleher
  • 1,952
  • 1
  • 23
  • 34
  • 2
    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 `` and `` directly into my html `
    ` 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.
    – sfscs Nov 13 '19 at 18:33
  • Can I use this method when I have inlined template? Like: `
    my template is here
    `. Because we have mix of laravel and vue, where views are composed by laravel and than on frontend just enhanced by Vue.
    – Luckylooke Mar 12 '20 at 18:20
  • 1
    @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 https://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! – Sean Kelleher Mar 14 '20 at 11:19