Why is my Vue view not being found by Typescript (or possibly Webpack)?

npx webpack

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

I am currently utilizing webpack, vue, and typescript.

My webpack configuration is pretty basic. It uses a typescript file as the entry point and generates output in a 'build' folder. I have included the typescript loader and vue loader in the setup.

The build process was smooth until I decided to switch from JavaScript to Typescript (e.g. renaming app.ts to app.js and removing the typescript loader resulted in everything working fine).

To address Vue related issues, I created a tsconfig.json file which helped in reducing errors but one issue persists as indicated above.

(I am taking an approach of learning webpack-vue-typescript step by step without relying on vue cli or vue ui. Though I did use vue cli to generate a vue typescript skeleton project for reference purposes. Upon comparison, I couldn't pinpoint any differences between my code and the one generated by vue cli.)

Complete error message along 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

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 serves as the entry point in app.ts:

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

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

Content of App.vue:

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

Webpack.config.js file:

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 details:

{
    "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"
    }
}

Contents of 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 content:

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

Versions:

  • npm 6.14.8
  • node 14.15.0
  • tsc 4.0.5
  • For other versions, refer to the package.json provided above.

Answer №1

I managed to resolve the issue by referring to the following two resources:

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

Within the src directory, I included a file named vue-shims.d.ts

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

Referencing the information provided in the aforementioned links

Single File Components ... In addition, we need to specify the structure of .vue files to TypeScript when they are imported. This is achieved through a vue-shims.d.ts file.

No explicit importing of this file is necessary. TypeScript automatically incorporates it, instructing that any imported file ending in .vue should conform to the Vue constructor's format.

Subsequently, a minor modification was made to the typescript module loader within webpack

 module: {
    rules: [{
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
            //Various parameters are defined for ts-loader facilitating the integration of TypeScript with Vue.
            //Specifically, appendTsSuffixTo: [/\.vue$/] has been set in our webpack.config.js file
            //as per the documentation at https://github.com/TypeStrong/ts-loader#appendtssuffixto
            appendTsSuffixTo: [/\.vue$/],
        },

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

Load Angular component on demand with necessary dependencies

Searching for an elegant solution (without resorting to private APIs) to create a widget-style dashboard. The goal is to dynamically load components based on user role. Is there a way to import a component and its dependencies included in the component&ap ...

Incorporating HTML code within a .ts file: a basic guide

I'm relatively new to Angular, but I've been given a project that's built with Angular. As I examine the .ts file containing the list of property types, I need to wrap a span around the label text. Is this doable? Here is the current list ...

Establish a public-facing link for a React component

After developing a React component that functions as a chatbot window, I am now looking for a way to make the opening button accessible across various websites and applications. My initial thought was to associate a URL with the button so that it can be ea ...

Ending the connection in SignalR upon $destroy

I am currently working on a page that is utilizing SignalR, Angular, and Typescript. Upon the destruction of the current $scope (such as during a page change), I make an attempt to disconnect the client from the SignalR server: Controller.ts $scope.$on(&q ...

Issue with displaying paragraph in Vue Js is resolved, however the checkbox functionality is still not working as expected

Upon mounting, I need to make the same POST API call three times and store the response in vuex. When I display the responses using: {{answer1}} // displayed 2 {{answer2}} // displayed 1 {{answer3}} // displayed 0 However, the checkbox does not wor ...

Guide to personalizing the variables in Vuetify within a Laravel project

Currently, I am incorporating vuetify within Laravel. My Laravel 8 project is set up with Vue version 2 using the laravel/ui package. So far, everything appears to be functioning correctly with all vuetify components rendering as expected. However, when at ...

Restoring previous configuration in Ionic2 from the resume() lifecycle method

Encountering an issue with my ionic2 application where I save the last state in local storage when the app goes to the background. Upon resuming, it checks for the value of lastState in local storage and pushes that state if a value exists. The specific er ...

Warning: The use of the outdated folder mapping "./" in the "exports" field for module resolution in the package located at node_modulespostcsspackage.json is deprecated

I recently upgraded my Node to version 16 and since then I have been encountering this issue while building my Angular app. Warning: The folder mapping "./" used in the "exports" field of the package located at ".../node_modules/postcss/package.json" is de ...

Can you test a Vue 3 Composition library that utilizes inject without using a container component?

I am currently referring to a tutorial on developing an authentication composition library by following this guide: Essentially, you create a file /src/components/auth/index.ts where you define refs and "use" functions that are then directly exported. Her ...

Tips for creating a script that waits for a specific amount of time before moving on to the next execution block in Protractor

Need to automate a test case that involves filling out a form with 5 date pickers and 30 fields. Once the form is filled, a jar needs to be invoked to retrieve the data from the DB and process it independently. Note: The jar does not send any value back t ...

Executing the Axios Interceptor

Trying to implement the logging feature but struggling to follow the documentation provided at: https://github.com/hg-pyun/axios-logger Even though I am getting the expected results, I am curious about running it in Vue.js similar to the image displayed. ...

What is the process for defining a recursive array data structure?

Looking to implement a TypeScript method that can navigate through nested arrays of strings when given an instance of a type/class/interface. The method, in concept, should resemble: method<T>(instance: T, arrayAttr: someType) { let tmp = undefin ...

A guide to retrieve data attributes in Vue.js

When my button is clicked, a modal pops up with data passed through data attributes. The button code looks like this: <button class="edit-modal btn btn-info" data-toggle="modal" data-target="#editModal" :data-id=item.id ...

The absence of a template or render function in a Vue.js 3 and Quasar 2 component has resulted in an

I am currently working on creating a dynamic component and passing a prop to it. However, I am encountering a warning message that says: Component is missing template or render function. Although the component is being rendered, I am still receiving the wa ...

Typescript is failing to perform type checking

I'm encountering an issue while trying to utilize TypeScript type checking with the following code snippet: abstract class Mammal { abstract breed(other: Mammal); } class Dog extends Mammal { breed(other: Dog) {} } class Cat extends Mammal { ...

Moving SVG Module

My goal is to create a custom component that can dynamically load and display the content of an SVG file in its template. So far, I have attempted the following approach: icon.component.ts ... @Component({ selector: 'app-icon', templa ...

When a MatFormFieldControl both implements ControlValueAccessor and Validator, it can potentially lead to a cyclic

I am attempting to develop a custom form control by implementing MatFormFieldControl, ControlValueAccessor, and Validator interfaces. However, I encounter issues when including NG_VALUE_ACCESSOR or NG_VALIDATORS. @Component({ selector: 'fe-phone-n ...

You must provide a value for a v-bind expression; an empty value was detected in "v-bind:items"

I am completely new to using Vue. I have a vue component that I am working with, where I pass some objects through the component if they are available. Here is an example of how I'm using it: <form :languages='{{ json_encode($languages) }}&apo ...

Tips for triggering a function when the range slider is adjusted

I'm looking to trigger a function whenever a user changes a range slider in my Vue.js project, and I also need to pass the new value to that function. The code snippet below shows what I have so far. <div cla ...

Access NgModel from NgForm

Is there a way to access the NgModel of a FormControl retrieved from the NgForm.controls object within its parent form, or directly from the form itself? Upon form submission, I pass the form as a parameter to a custom function: <form #myForm="ngForm" ...