Failed to mount component when change .vue file to lang="ts"

need to build single file component vue project using webpack directly, not use vue-cli …

when I build the project using javascript, the code works. I change to lang=“ts” and I get a “failed to mount component” error.


import Vue from 'vue'
import App from './App.vue'
new Vue({
  el: '#app',
  render: h => h(App)


		<h1>My Todo App!</h1>
		<p>something else</p>

<script lang="ts" >
  import Vue from 'vue';
export default Vue.extend({


<!DOCTYPE html>

  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <title>My Vue app with webpack 4</title>

  <div id="app"></div>
  <script src="dist/main.js" type="text/javascript"></script>



  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./lib",
    "strict": true,
    "lib": [
  "sourceMap": true,
  "rootDir": "src",
  "exclude": [


'use strict'
const path = require("path");
const { VueLoaderPlugin } = require('vue-loader');

module.exports = {
  mode: 'development',
  entry: ['./src/app.ts',],

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'main.js'

  module: {
    rules: [
        test: /\.scss$/,
        use: [
          "style-loader", // 3. inject styles indo dom
          "css-loader",   // 2. turn css into commonjs
          "sass-loader"  // 1. scss into css
        use: 'ts-loader'
        test: /\.vue$/,
        use: ['vue-loader', 'ts-loader']

  plugins: [
    new VueLoaderPlugin()

the error message in the browser:

vue.runtime.esm.js:620 [Vue warn]: Failed to mount component: template or render function not defined.

found in

---> <App> at src/App.vue
warn @ vue.runtime.esm.js:620

I get build errors when I do not include ts-loader in the webpack build of .vue files. But when I do include ts-loader, that is when I get the run time “failed to mount component” error.

        test: /\.vue$/,
        use: [
          { loader: 'ts-loader' },
        {loader: 'vue-loader',
        options: {
          loaders: {
            // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
            // the "scss" and "sass" values for the lang attribute to the right configs here.
            // other preprocessors should work out of the box, no loader config like this necessary.
            'scss': 'vue-style-loader!css-loader!sass-loader',
            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
          // other vue-loader options go here

This is all OK now. I needed to use @Component decorators and typescript classes in the .vue “single file component” files.