Why am I getting "Cannot find module..." Typescript error for ".vue" file on webpack-dev-server recompilation?

710 Views Asked by At

I've setup a small webpack project which creates a Vue app bundle which is included in a static HTML file where the app is injected. I want to have components written in Typescript so I've included ts-loader in the webapck configuration. The build process - using the "webpack" command - works ok, but I'm having some trouble when I use webpack-dev-server.

When I initially start the server, everything works fine: the bundle is created and served on my local server and the browser displays the app correcly. However, when I make a change in the source code and save, I get a Typescript error when the code is recompiled telling me that a module or declaraton is missing for the ".vue" file for my component:

TS2307: Cannot find module './components/Banner.vue' or its corresponding type declarations.

To start the server I use the following command:

webpack serve --open

Project's folder structure

=======

webpack.config.js

const { VueLoaderPlugin } = require('vue-loader')
const path = require('path')

module.exports = {
  mode: 'development',
  devtool: 'inline-source-map',
  entry: {
    app: './src/app.js',
  },
  output: {
    filename: '[name].bundle.js',
  },
  plugins: [
    new VueLoaderPlugin(),
  ],
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: ['vue-loader']
      },
      {
        test: /\.ts$/,
        loader: 'ts-loader',
        exclude: [/node_modules/],
        options: { appendTsSuffixTo: [/\.vue$/] }
      },
    ],
  },
}

app.js

import Vue from 'vue'
import App from './App.vue'

const app = new Vue({
  render: (h) => h(App)
})

app.$mount('#app')

App.vue

<template>
  <div id="app">
    <h1>{{ welcomeMessage }}</h1>
    <Banner />
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Banner from './components/Banner.vue'

export default Vue.extend({
  components: {
    Banner,
  },
  data: () => ({
    welcomeMessage: 'Hello world!'
  })
})
</script>

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "strict": true,
    "module": "es2015",
    "moduleResolution": "node"
  }
}

@types/vue-shims.d.ts

declare module "*.vue" {
  import Vue from 'vue'
  export default Vue
}

package.json

{
  "name": "2021-06-21-webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "dev": "webpack serve --open"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^8.3.0",
    "typescript": "^4.3.4",
    "vue-loader": "^15.9.7",
    "vue-template-compiler": "^2.6.14",
    "webpack": "^4.46.0",
    "webpack-cli": "^4.7.2",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    "vue": "^2.6.14"
  }
}
0

There are 0 best solutions below