Vuejs Error: "No template or render function defined for a single file component"

When attempting to import all components from a folder and display one based on a passed prop, I encountered an error at runtime.

I am using webpack with vue-loader to import all my components, each of which is a *.vue file.

The issue arises when importing components stored in a subfolder. An error message is displayed at runtime:

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

found in

---> <Test2>
       <VoneDocs> at src\components\VoneDocs.vue
         <App> at src\App.vue
           <Root>

After some research and help from @craig_h, it was determined that the problem stemmed from how the files were being imported:

<template>
  <transition name="fade">
  <div class="vone-docs" v-if="docName !== undefined">
    <component :is="docName"/>
  </div>
  </transition>
</template>

<script>
import Test from '../assets/docs/Test';

// Importing all docs (*.vue files) in '../assets/docs'
let docsContext = require.context('../assets/docs', false, /\.vue$/);
let docsData = {}; 
let docsNames = {};
let docsComponents = {};
docsContext.keys().forEach(function (key) {
  docsData[key] = docsContext(key); 
  docsNames[key] = key.replace(/^\.\/(.+)\.vue$/, '$1'); 
  docsComponents[docsNames[key]] = docsData[key]; 
});

export default {
  name: 'vone-docs',

  props: ['page'],

  components: {
    ...docsComponents,
    Test
  },

  computed: {
    docName () {
      return this.page;
    },

    docFileName () {
      return './' + this.docName + '.vue';
    },

    docData () {
      return docsData[this.docFileName];
    }
  },

  beforeRouteUpdate (to, from, next) {
    if (to.path === from.path) {
      location.hash = to.hash;
    } else next();
  },

  mounted () {
    console.log(docsComponents);
  }
};
</script>

Although the Test component displays successfully when docName is set to 'test' due to direct import, every other Vue single-file-component imported using require.context() results in the error:

Failed to mount component: template or render function not defined.

Is there something wrong with how Iā€™m using require.context()?

Below is my webpack configuration (excluding raw-loader and html-loader, following Vue's webpack-template structure):

// webpack.base.conf.js
'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')

function resolve (dir) {
  return path.join(__dirname, '..', dir)
}

module.exports = {
  context: path.resolve(__dirname, '../'),
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
    publicPath: process.env.NODE_ENV === 'production'
      ? config.build.assetsPublicPath
      : config.dev.assetsPublicPath
  },
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
    }
  },
  module: {
    rules: [
      ...(config.dev.useEslint? [{
        test: /\.(js|vue)$/,
        loader: 'eslint-loader',
        enforce: 'pre',
        include: [resolve('src'), resolve('test')],
        options: {
          formatter: require('eslint-friendly-formatter'),
          emitWarning: !config.dev.showEslintErrorsInOverlay
        }
      }] : []),
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test')]
      },
      {
        test: /\.(png|jpe?g|gif)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.raw\.svg$/,
        loader: 'raw-loader'
      },
      {
        test: /\.icon\.svg$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('media/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
        }
      },
      {
        test: /\.(html)$/,
        use: {
          loader: 'html-loader',
          options: {
            attrs: [':data-src', 'img:src']
          }
        }
      }
    ]
  }
}

Thank you for any assistance!

Answer ā„–1

Got it, if you're using the build without the template compiler, then you won't be able to use the template property. Instead, you should mount your base component (the one containing router-view) to your main view instance by using a render function:

import App from './components/App.vue'

new Vue({
  el: '#app',
  router,
  render: h => h(App) // This will connect the base component (App.vue) to `#app`
})

Just remember that your base component must also be a .vue file.

The other day I posted a detailed explanation on setting up a Vue SPA which might help you out: vue-router how to persist navbar?

Answer ā„–2

After much contemplation, I have successfully resolved the issue at hand.

According to Linus Borg in this forum post on vue.js, it is noted that vue-loader does not normalize exports as expected.

let docsData = {};

function importAllDocs (r) {
  r.keys().forEach(function (key) {
    docsData[key.replace(/^\.\/(.+)\.vue$/, '$1')] = r(key).default;
  });
}

importAllDocs(require.context('../assets/docs', true, /\.vue$/));

The key to solving the problem was accessing r(key).default instead of just r(key).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide for registering to modifications of a single key within a form group in Angular 2

I am facing an issue with my userForm group that consists of keys name, email, and phone. I have implemented an onValueChanged function to validate these fields whenever they are changed. However, the validation runs every time even if the field has not ...

What methods can be used by the client-side to determine whether a file has been successfully downloaded or received from

When a client-side file download request is initiated, I dynamically create a form element with hidden attributes and submit it to the server via POST. During this process, I need to display a loading spinner that will be hidden once the download is comple ...

What could be causing my code to fail in the useEffect hook every time I make updates to my JSON

I have a function that receives JSON data from the server. Using the {jsonData.map((element) => renderComponents(element, jsonData))} function, I loop through the data and send each object to the renderComponents function along with the full JSON data. ...

Trigger a function when the value of the file input field changes using ng-change

I'm attempting to trigger my upload() function when the file input changes, but I'm having trouble getting it to work. This is the HTML code: <input type="file" ng-model="image" ng-change="uploadImage()"> And here's the correspondin ...

The sidebar in tailwind css is not displaying a scrollbar as expected

I'm currently working on a project to create a WhatsApp clone using Tailwind CSS in ReactJS. However, I've encountered an issue with the contacts list where it's not showing the scrollbar and instead overflowing the content, leading to the w ...

The Datalist feature in HTML5 offers an auto-suggest functionality that displays a list of options beginning with the

In my project, I am utilizing HTML5 Datalist for autosuggestion. By default, HTML5 follows the keyword contains approach rather than the starts with approach. For example, if my datalist includes one, two, three and I type "o" in the search box, it displ ...

Is it possible for the data submitted in a POST request to be converted into URL parameters?

Our technology stack: Frontend built with Vue.js and utilizing the vuetify component library Custom Python middleware REST API using Flask + Tornado External Matomo setup connected to the frontend via the vue-matomo plugin system (https://github.com/Amaz ...

What happens to the npm package if I transfer ownership of a github repository to a different user?

I was considering transferring a GitHub repository to another user or organization, but I have concerns about what will happen to older versions of the npm package associated with it. Let's say my Node.js package is named node-awesome-package. Versi ...

When an SVG image is embedded, its color may not change even after being converted to an inline SVG

I've inserted an SVG using an img tag. When hovering over it, I want the fill color of the SVG to change. I attempted to convert the SVG to inline SVG following this method, but it doesn't seem to be working as expected. No console errors are b ...

Sort by label using the pipe operator in RxJS with Angular

I have a situation where I am using an observable in my HTML code with the async pipe. I want to sort the observable by the 'label' property, but I'm not sure how to correctly implement this sorting logic within the pipe. The labels can be e ...

What is the most efficient method for conditionally rendering components in React?

I'm currently in a dilemma about how to render a component based on a certain condition in React. Which way is considered the best practice? Your expertise would greatly assist me as I navigate through this decision-making process. First approach: co ...

Error encountered in Typescript: SyntaxError due to an unexpected token 'export' appearing

In my React project, I encountered the need to share models (Typescript interfaces in this case) across 3 separate Typescript projects. To address this, I decided to utilize bit.env and imported all my models to https://bit.dev/model/index/~code, which wor ...

Getting a specific value from a REST API array in JavaScript: Tips and tricks

After being stuck on this problem for 8 hours, I finally decided to seek help: In my JavaScript file, I am attempting to extract data from a REST API response. The response consists of an array of objects structured like this: [{"start":"2017-04-21 14:40 ...

Why is it possible for me to call a function that is defined below a component?

My understanding was that in Javascript, functions could not be invoked if they are defined below where they're called (unless hoisting is involved). However, I discovered something interesting while working with React. The code snippet below actuall ...

A guide to integrating Material-UI with your Meteor/React application

I encountered an issue while trying to implement the LeftNav Menu from the Material-UI example. The error message I received is as follows: While building for web.browser: imports/ui/App.jsx:14:2: /imports/ui/App.jsx: Missing class properties transf ...

Combining and visualizing multiple datetime series in Highcharts

Is there a way to overlay two datetime x-axes that have different date ranges but the same number of data points? I want point index x from series 1 to line up with point index x from series 2. I attempted to do this by using two x-axes, one of which is h ...

Make Bootstrap Panel Full Width with Highcharts Data

I am currently working on displaying graphs using the Highcharts library on three televisions. All televisions have a FULL HD resolution of 1920 x 1080. I have one Bootstrap panel containing a graph in the panel-body. <div class="panel panel-blue"> ...

Is there a way to attach a mouseover event to a Vue ref element in Javascript?

I want to remove the mouseOver event from the template using $ref and control the mouseOver behavior within javascript. The Components component contains a child component called myStats, which should only be displayed when hovering over Components. I nee ...

Deliver an assured result to a variable within the angular.extend() function

Can someone provide guidance on how to set myVar to a value returned from an asynchronous service method in the following example? angular.extend(this, { myVar: (function() { getVal(); })() }); function getVal() { var d = $q.defer(); ...

What is the procedure for inputting the settings for the export module in webpack?

I am currently working on setting up this webpack configuration file. However, I encountered an issue where the error message states that "any" is being used as a value instead of a type. How can I resolve this issue? module.exports:any = { ...