What is the best method for eliminating the .vue extension in TypeScript imports within Vue.JS?

I recently created a project using vue-cli3 and decided to incorporate TypeScript for added type safety.

Here is a snippet from my src/app.vue file:

<template>
  <div id="app">
    <hello-world msg="test"/>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from '@/components/HelloWorld';

@Component({
  components: { HelloWorld },
})
export default class App extends Vue {}
</script>

Unfortunately, the compiler is returning an error stating "Cannot find module '@/components/HelloWorld'". However, I can confirm that the component HelloWorld does indeed exist.

Interestingly, if I either remove the lang="ts" attribute or add the .vue extension, everything compiles without any issues. In my tsconfig.json file, I have defined paths as follows:

  "paths": {
    "@/*": [ "src/*" ]
  },

Could this be an issue with the tsconfig.json configuration or something else causing this error?

Answer №1

If you navigate to the root folder of your sources, you may come across a file called shims-vue.d.ts containing code similar to this:

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

This particular file informs the Typescript compiler that any file ending in .vue should be associated with the Vue type. Without this declaration, Typescript will not recognize the type and encounter difficulties during compilation.

The significance of retaining the .vue extension lies in enabling Typescript to properly interpret and compile the files according to their assigned types. In essence, removing the extension is not advisable as it would impede the compiler's ability to process the files accurately.

More technically:

In theory, it is possible to eliminate the extension; however, doing so requires creating a custom module shim specifying the appropriate expression for all files within a designated directory. Despite its feasibility, this approach is considered less efficient compared to simply utilizing the standard .vue extension shim.

Answer №2

It is essential to include the .vue extension at the end of each Vue.js component when importing them.

`import HelloWorld from '@/components/HelloWorld';

The correct way should be:

 import HelloWorld from '@/components/HelloWorld.vue'

Answer №3

In order to streamline your workflow, consider adding the awesome-typescript-loader package to your setup. This will allow you to import files without needing to include the .vue extension. Additionally, if you are utilizing SCF components, make sure that you have both the vue-loader package installed and the shims-vue.d.ts file in place.

Answer №4

If you are a WebStorm (JetBrains) IDE user, you have the option to automatically append the ".vue" extension when creating a new component:

Click here for more information..

Answer №5

The line

import HelloWorld from '@/components/HelloWorld';
should actually be
import HelloWorld from '@/components/HelloWorld.vue
.

This confusion arises because the compiler assumes that @/components/HelloWorld is a .ts or .js file, which does not exist in reality.

Answer №6

Even though this question is a bit old, it appears that adding the shim-vue.d.ts file may be necessary.

//shims-vue.d.ts

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

For more information, you can visit: What does the shims-tsx.d.ts file do in a Vue-Typescript project?

Answer №7

If your components folder contains only .vue files, you may want to consider inserting the following code snippet into your shims-vue.d.ts file:

declare module '@/components/*' {
    import Vue from 'vue'
    export default 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

Issues encountered when attempting to refresh page with react-router-dom

I successfully implemented a private route system in my React application using react-router-dom. However, I encountered an issue where upon reloading a page, it briefly redirects to /login before properly displaying the page. How can I resolve this unexpe ...

Create a notification box that appears after a successful axios request

One of the functions I have is to store an expense in my application. storeExpense(context, params){ axios.post('api/expenses', params) .then( response => { context.dispatch('getExpenses') }) .catch( error =&g ...

Utilizing Array Notation in Typescript to Retrieve Elements from Class

In my programming project, I am working with two classes: Candles and Candle. The Candles class includes a property called list, which is an array containing instances of the Candle class. class Candles { public list: Array<Candle>; } class Candl ...

Maintain Vue Router Query Parameters Across Parent Components

In my application, I have a component named Foo, which serves as the template for a route called app/foo. Within this component, there are child components that also act as templates for routes such as app/foo/bar and app/foo/baz. I've implemented a ...

An error occurred: gyp ERR! stack - The command `python -c import sys; print "%s.%s.%s" % sys.version_info[:3]` has failed

While attempting to npm install in a Vue project, I encountered an error even after running vue create (name): npm ERR! gyp verb check python checking for Python executable "c:\Python310\python.exe" in the PATH npm ERR! gyp verb `which` ...

iOS 10.3.1 causing Ionic 2 (click) event to trigger twice

I am currently working on an Ionic 2 app and I am facing an issue with the click event. When I test the app on a device and click on a button, let's say to trigger an alert, the function executes once. However, if I click on the button again, the fun ...

Is it preferable to share the .vue file or the compiled component in Vue?

When creating unique components, is it more advantageous to release the original .vue file or distribute a compiled version through webpack or another bundling tool? Additionally, is there an official reference document outlining best practices for releas ...

What is the best way to dynamically add a class to the right navigation element in Vue.js when the :class binding only accepts boolean values?

My issue involves implementing a fixed navigation bar with the following structure: <nav class='navigation'> <div :class="{ active: }" @click='scrollTo(".test1")'></div> <div :class=" ...

The issue arises when interfaces are extended by another interface

Is there a way to have classes that implement both the Observer and Comparable interfaces together? interface Comparable<T> { equals: (item: T) => boolean; } interface Observer extends Comparable<Observer> { notify: () => void } ...

Error code TS1005: Compiling Typescript DefinitelyTyped assets encountered an issue

I'm confident in my setup, but I can't seem to get tsc to compile. Here's the branch of my repository: https://github.com/inosion/sample-atom-typescript-package/tree/add_react Although I have the latest versions of typescript, I'm uns ...

What could be causing the strange output from my filtered Object.values() function?

In my Vue3 component, I created a feature to showcase data using chips. The input is an Object with keys as indexes and values containing the element to be displayed. Here is the complete code documentation: <template> <div class="row" ...

What is the best way to display the arrows on a sorted table based on the sorting order in Angular?

I need assistance with sorting a table either from largest to smallest or alphabetically. Here is the HTML code of the section I'm trying to sort: <tr> <th scope="col" [appSort]="dataList" data-order ...

Unable to resolve every parameter

I am facing an issue while trying to inject a service into my component, resulting in the following error: https://i.stack.imgur.com/zA3QB.png news.component.ts import { Component,OnInit } from '@angular/core'; import { NewsService } from &apo ...

Unable to retrieve JSON data from php script, but able to successfully retrieve it from file.json

This is the function of my PHP testing script: $json = array ( "age" => 5, "name" => "Lee", ); $json = json_encode($json); echo $json; The JSON data is successfully printed out. When I save its content in a file named file.json and read ...

The MatInput value will only display after the page is reloaded or refreshed

After refreshing the page, a matInput field displays a value or result that was previously hidden. https://i.stack.imgur.com/q9LQI.png By selecting or highlighting within the matInput, the value or result becomes visible. https://i.stack.imgur.com/SqaLA.p ...

In TypeScript, the nested object structure ensures that each property is unique and does not repeat within

Here is the current state of my interface. I am wondering if there is a way to streamline it to avoid repeating properties in both parts. export interface Navigation { name: string; roles: Array<number>; sublinks: NavigationItem[]; } ...

The test session failed to launch due to an error in initializing the "@wdio/cucumber-framework" module. Error message: [ERR_PACKAGE_PATH_NOT_EXPORTED]

I added @wdio/cli to my project using the command 'npm i --save-dev @wdio\cli'. Next, I ran 'npx wdio init' and chose 'cucumber', 'selenium-standalone-service', 'typescript', 'allure' along w ...

Updating the parent's data by modifying data in the child component in VueJS

When I use multiple components together for reusability, the main component performs an AJAX call to retrieve data. This data is then passed down through different components in a chain of events. <input-clone endpoint="/api/website/{{ $website->id ...

Issue with implicitly assigning 'any' type to overloaded variadic generic function

We have some code snippets for you to review: export type actions = { abort: () => void; back: () => void; next: () => void; resume: () => void; }; class Sabar { public use<T1>(fn: (arg1: T1, ctx: object, actions: actions) =&g ...

What is the best way to verify values in Vuejs based on their length?

<button type="submit" :disabled="(user.password && !$v.user.password.valid) || (user.confirmPassword && !$v.user.confirmPassword.sameAsPassword)">sda </button> By implementing a method based on character len ...