简体   繁体   中英

“Failed to mount component: template or render function not defined” in Vue, despite using full compiler bundle

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/vue@2.5.13/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'
        },
    }
};

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM