0

I am trying to develop a re-usable Vue component. It is setup to build using webpack, and then a demo page loads the full Vue compiler and this compiled bundle onto a page. However, on loading the page I receive the following error, despite having included the Vue compiler.

[Vue warn]: Failed to mount component: template or render function not defined.

found in

---> <Cwl>
       <Root>

I would have thought that the vue-loader would have set the template field of the cwl component, and I would have thought that the Vue version I added to my page would include the compiler. What am I missing here?


The code in question can be seen at this GitHub URL. Simply clone the repo, run webpack, start a server with http-server, and then browse to http://localhost:8080/demo/.

For reference, my demo HTML page looks like this:

<!DOCTYPE html>
<html lang="en">
<body>
<div id="vue" class="container container-fluid">
    <cwl
            cwl-url="https://rawgit.com/rabix/cwl-svg/master/cwl-samples/fastqc.json"
    ></cwl>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="../dist/index.js"></script>
<script>
    Vue.config.devtools = true;
    Vue.config.debug = true;
    new Vue({
        el: '#vue',
        components: {
            cwl: vue_cwl
        }
    })
</script>
</body>
</html>

And my webpack config looks like this:

const path = require("path");

module.exports = {
    devtool: "source-map",

    // Read files from js/src
    entry: './cwl.vue',

    // Output everything into the static folder
    output: {
        libraryTarget: "umd",
        path: path.resolve("dist/"),
        filename: "index.js",
        library: 'vue_cwl'
    },

    externals: {
        vue: 'vue'
    },

    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
            },
            {
                test: /\.js$/,
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [require('babel-preset-env')]
                    }
                },

            },
            {
                enforce: "pre",
                test: /\.ts?$/,
                exclude: ["node_modules"],
                use: {
                    loader: "awesome-typescript-loader",
                    options: {
                        useBabel: true
                    }
                }
            },
            {test: /\.css$/, loaders: ["style-loader", "css-loader"]},
            {
                test: /\.scss$/,
                use: [{
                    loader: "style-loader" // creates style nodes from JS strings
                }, {
                    loader: "css-loader" // translates CSS into CommonJS
                }, {
                    loader: "sass-loader" // compiles Sass to CSS
                }]
            }
        ]
    },
    resolve: {
        extensions: [".ts", ".js", ".vue"],
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        },
    }
};
3
  • I have no clue how to fix this, because I always used the webpack template from the vue-cli. In that way everything works out of the box and you never even have to look at webpack configs. Maybe give it a try? npmjs.com/package/vue-cli Commented Feb 18, 2018 at 8:14
  • What's strange is my webpack.config looks a lot like the vue-cli one: github.com/vuejs-templates/webpack-simple/blob/master/template/…. But I'll give it a go anyway Commented Feb 18, 2018 at 8:45
  • Yeah, really don't know. I try to avoid configuring development environments as much as possible. In my opinion that should be something that just works. The vue webpack and webpack-simple templates just work :). Commented Feb 18, 2018 at 10:16

1 Answer 1

2

If you console.log(vue_cwl) you can see there is a default property which contains the actual Vue component. Change your code to use the default property as the component:

components: {
    cwl: vue_cwl.default
}

From my answer to a similar question:

A Vue component is usually exported with export default { /* ... */} so it facilitates the default import like import Component from './component.vue'(ES6 syntax)

When using require() (CommonJS) you have to specify you are requiring the default export

In your case you are including directly the component via <script> but the concept remains.

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

Comments

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.