0
votes

npx webpack

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

I'm using webpack, vue and typescript.

I have basic webpack configuration. It has as entry point a typescript file. Output is a folder build. I am using the typescript loader and the vue loader.

The build works fine until I changed from javascript to typescript (i.e. if I renamed app.ts to app.js and remove the typescript loader from webpack everything works).

For vue I have added tsconfig.json file. This helped reduce the errors. But I still get this one error shown above.

(I am trying to learn webpack-vue-typescript from first principles. So I do not want to use vue cli or vue ui. Although I did generate a vue typescript skeleton project with vue cli. I compared my code with the vue cli code. I cannot find any differences.)

Here is the full error message (with a warning)

npx webpack
[webpack-cli] Compilation finished
assets by status 64.1 KiB [cached] 1 asset
orphan modules 227 KiB [orphan] 7 modules
runtime modules 495 bytes 2 modules
./src/app.ts + 7 modules 227 KiB [built] [code generated]

WARNING in ./src/App.vue?vue&type=script&lang=ts& 1:166-169
export 'default' (imported as 'mod') was not found in '-!../node_modules/ts-loader/index.js!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=script&lang=ts&' (possible exports: )
 @ ./src/App.vue 2:0-55 3:0-50 3:0-50 9:2-8
 @ ./src/app.ts 2:0-28 4:36-39

ERROR in \src\app.ts
[tsl] ERROR in D:\code\vue\fs\src\app.ts(2,17)
      TS2307: Cannot find module './App.vue' or its corresponding type declarations.

webpack 5.4.0 compiled with 1 error and 1 warning in 3364 ms

Folder structure

+-- package.json
+-- webpack.config.js
+-- tsconfig.json
+-- src
    +-- app.ts
    +-- App.vue
    +-- index.html

This is the entry point app.ts

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

new Vue({
    render: h => h(App)
}).$mount('#app')

App.vue

<template>
  <div>hello from vue</div>
</template>

Webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const path = require('path');

module.exports = {
    entry: './src/app.ts',
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: '[name].js'
    },
    plugins: [
        new HtmlWebpackPlugin({ template: './src/index.html' }),
        new VueLoaderPlugin(),
        new CleanWebpackPlugin()
    ],
    devServer: {
        inline: true
    },
    module: {
        rules: [{
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.vue$/,
                use: 'vue-loader'
            }
        ]
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js']
    }
};

package.json

{
    "name": "vue_ts",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "scripts": {
        "start": "webpack serve",
        "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
        "clean-webpack-plugin": "^3.0.0",
        "html-webpack-plugin": "^4.5.0",
        "ts-loader": "^8.0.11",
        "typescript": "^4.0.5",
        "vue-class-component": "^7.2.6",
        "vue-loader": "^15.9.5",
        "vue-property-decorator": "^9.0.2",
        "vue-template-compiler": "^2.6.12",
        "webpack": "^5.4.0",
        "webpack-cli": "^4.2.0",
        "webpack-dev-server": "^3.11.0"
    },
    "dependencies": {
        "vue": "^2.6.12"
    }
}

tsconfig.json

{
    "compilerOptions": {
        // this aligns with Vue's browser support
        "target": "es5",
        // this enables stricter inference for data properties on `this`
        "strict": true,
        // if using webpack 2+ or rollup, to leverage tree shaking:
        "module": "es2015",
        "moduleResolution": "node"
    },
    "include": [
        "src/**/*.ts",
        "src/**/*.tsx",
        "src/**/*.vue",
        "tests/**/*.ts",
        "tests/**/*.tsx"
    ],
    "exclude": [
        "node_modules"
    ]
}

index.html

<html>
<head></head>
<body>
    <div id="app"></div>
</body>
</html>

Versions

  • npm 6.14.8
  • node 14.15.0
  • tsc 4.0.5
  • other version please package.json above
1

1 Answers

1
votes

I resolved the problem following these 2 links

  1. https://johnpapa.net/vue-typescript/
  2. https://github.com/microsoft/typescript-vue-starter#install-our-dependencies

Under the src folder I added this file vue-shims.d.ts

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

From the 2 links above

Single File Components ... One extra thing we'll have to do is tell TypeScript what .vue files will look like when they're imported. We'll do this with a vue-shims.d.ts file.

We don't need to import this file anywhere. It's automatically included by TypeScript, and it tells it that anything imported that ends in .vue has the same shape of the Vue constructor itself.

And then the typescript module loader in webpack needed a slight change

 module: {
    rules: [{
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
            //Then there are settings for a ts-loader, which helps load the TypeScript with Vue.
            //We also specified the appendTsSuffixTo: [/\.vue$/], option to ts-loader in our webpack.config.js file, 
            //which allows TypeScript to process the code extracted from a single file component.
            //https://github.com/TypeStrong/ts-loader#appendtssuffixto
            appendTsSuffixTo: [/\.vue$/],
        },