Troubleshooting: Unable to locate .vue.d.ts file during declaration generation with Vue, webpack, and TypeScript

Currently, I am developing a library using Typescript and VueJS with webpack for handling the build process.

One of the challenges I'm facing is related to the generation of TypeScript declaration files (.d.ts).

In my source code, I have Typescript files along with Vue components. Each Vue component consists of two files: a .vue file and a .ts file.

For example:

Consider the following code snippet:

// index.ts
export { default } from './components/Foobar.vue';

// components/Foobar.vue
<template><p>Hello!</p></template>
<script lang="ts" src="./Foobar.ts"></script>

// components/Foobar.ts
@Component
export default class Foobar extends Vue {

}

After the build process, the output will look something like this:

lib/
dist/
    index.js // my lib
    index.d.ts // aggregated .d.ts with dts-bundle
    lib/ // all my .d.ts are here !
        index.d.ts
        components/
            Foobar.d.ts

The issue arises because dts-bundle fails to generate dist/index.d.ts due to invalid declarations (dist/lib/**/*.d.ts) created by ts-loader.

If we examine the content of dist/lib/index.d.ts, we see the following:

// dist/lib/index.d.ts
export { default } from './components/Foobar.vue'

The problem lies in the fact that /dist/lib/components/Foobar.vue does not exist. The correct definition for this component should be Foobar.d.ts, not Foobar.vue.d.ts.

During bundling, dts-bundle encounters difficulty finding /dist/lib/components/Foobar.vue.d.ts.

To resolve this issue, I simply need to replace the existing line:

// dist/lib/index.d.ts
export { default } from './components/Foobar.vue'

with:

// dist/lib/index.d.ts
export { default } from './components/Foobar'

This seems to be a common error, possibly originating from misconfiguration in my webpack setup. Here's a glimpse at my webpack configuration:

{
  mode: 'development',
  devtool: 'cheap-module-eval-source-map',

  entry: 'path/to/index.ts',

  output: { /* ... */}

  resolve: {
    symlinks: true,
    extensions: [
      '.ts',
      '.vue',
      '.js',
      '.json',
    ],
    modules: [
      'node_modules',
    ]
  },

  module: {
    noParse: /^(vue|vuex)$/,
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'cache-loader',
            options: {
              cacheDirectory: // cache path
            }
          },
          {
            loader: 'vue-loader',
            options: {
              cacheDirectory: // cache path
            }
          },
        ]
      },
      {
        test: /\.ts$/,
        use: [
          {
            loader: 'cache-loader',
            options: {
              cacheDirectory: // cache path
            }
          },
          {
            loader: 'babel-loader'
          },
          {
            loader: 'ts-loader',
            options: {
              appendTsSuffixTo: [
                /\.vue$/
              ],
            }
          }
        ]
      }
      // ...
  }

  plugins: [
    new ProgressPlugin(),
    new FriendlyErrorsWebpackPlugin({
      clearConsole: false
    }),
    new VueLoaderPlugin(),
    new ForkTsCheckerWebpackPlugin({
      vue: true,
      tslint: 'custom path to my file',
      formatter: 'codeframe',
    }),
    new CopyWebpackPlugin(
      [
        {
          from: 'assets',
          to: 'dist',
          ignore: [
            '.gitkeep',
            '.DS_Store'
          ]
        }
      ]
    ),      
    new DtsBundlePlugin({
      name: `MyModule`,
      main: path.join(LIB_PATH, entry.output.path, 'lib', 'index.d.ts'),
      out: path.join(LIB_PATH, entry.output.path, 'index.d.ts'),
      verbose,
    })
  ],
}

I am currently working on creating a minimal reproduction repository for this issue, which I will update as needed.

In the meantime, please let me know if additional information is required.

Thank you for your assistance.

Answer №1

Finally, after some trial and error, I was able to figure it out.

The role of vue-loader is to separate vue monofiles into various webpack assets. The intention is for webpack to apply different loaders to each section of a vue monofile (script, style, and template).

In my scenario, I didn't have a traditional vue monofile because the typescript portion was in a separate file from the .vue file. I referenced it using

<script lang="ts" src="./MyComponent.ts"></script>
.

This setup caused issues with declaration generation due to how ts-loader and vue-loader function.

To resolve this, I had to switch to using standard monofile components. However, since I needed to keep my ts code separate from my .vue file (due to a known bug in typescript), I had to import my ts module explicitly instead of referencing the file directly:

<script lang="ts">
    export { default } from './MyComponent.ts';
</script>

I hope that explanation clarifies things.

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

What is the best way to retrieve the `any` type when utilizing the `keyof` keyword?

I am struggling to articulate this question properly, so please refer to the code below interface TestParams<T> { order?: keyof T attr1?: number attr2?: string } async function Test<T = any>(_obj: TestParams<T>): Promise<T> { ...

Insert the picture into an HTML document and retrieve the image file location

I successfully used <input type="file" accept="image/*"> to upload an image and then applied base64 encoding of the image in the onload callback function of a FileReader instance. However, I encountered a problem when trying to assign this base64 enc ...

Does JSX/TSX markup act as a constant that is passed by value or by reference?

In a separate file called EmptyNode.tsx, I have defined a constant: export const EmptyNode = <></> This constant is used to return an empty node when there is no content to display. For example: ... render() { if(!this.props.data) { ...

Defining the TypeScript interface for the onClick event in ReactJS

If you're looking to dive into React development, the tutorial on reactjs.org is a great place to start. While the tutorial code is in JavaScript, I've been working on converting it to TypeScript. I've successfully translated most of the c ...

Typescript React Union type

I have developed a Card component with two different variants: Wrapper and Dashboard. Each variant comes with its own set of props. export type DashboardProps = { variant: CardVariant.Dashboard, primaryText: string, secondaryText: string, icon: Ove ...

Is the Child-Parent-Communication Method Lost?

I'm currently working on setting up communication between child and parent components in nuxtjs. Here is my child component: <div> <b-nav-item @click="clicked" :class="{active: active}">{{item.name}}</b ...

Create a custom Android home screen widget using JavaScript or another programming language

I have a project in mind to create an Android App and include a home-screen widget. While I know it can be done with Native Android, my preference is to use JavaScript for development. Would anyone happen to know of any other solutions that allow the use ...

Typescript decorator specifically designed for abstract generic Container class's child elements

Struggling with Typescript generics in my project, specifically with Typescript 2.6. My goal is to design a MobX store that implements a class decorator for basic authentication checks. This decorator should take a class type derived from the abstract gen ...

Monitoring Vue for ongoing HTTP requests

Upon mounting a component, it initiates 4 HTTP requests (using Axios) to fetch the necessary data. Is there a method to monitor for any outstanding HTTP requests? To simplify: Are there any pending HTTP requests? yes -> Loading=true no -> Loading ...

Filtering without specifying a data type and (with any luck) converting

Upon defining the function below: const filterAndCast = <T, U>( items: T[], predicate: Predicate<T>, cast: (x: T) => U, ) => items .reduce( (p, c) => [ ...p, ...(predicate(c) ? [cast(c)] ...

Tips for displaying CSS recommendations in JetBrains IDE (such as PyCharm) for your Nuxt project

Can anyone provide guidance on how to display CSS suggestions in JetBrains IDE (such as PyCharm)? They work fine in normal Vue projects with Vuetify, but for some reason they are not appearing in my Nuxt project. I currently have them working in my Vue pr ...

Clone a git project locally to a subdirectory within another project

Let me get straight to the point: ** background ** A few months ago, I started a project for a non-profit organization with some friends. Due to our non-charging nature, a couple of friends had to leave the project as they were swamped with their actual ...

beforeunload event confirmation prompt

I am currently working with Laravel and Vue.js to create a multi-step wizard. Within this wizard, I have implemented the onbeforeunload event to prevent any unwanted actions by displaying a confirmation message. However, I am encountering an issue where th ...

Consolidating Angular 4 Observable HTTP requests into a single Observable to optimize caching

I am currently working on an Angular 4 application that serves as a dashboard for a system. Several different components within the application make calls to the same REST endpoint using identical TypeScript service classes. While this setup functions corr ...

What might be causing my action function to be triggered during the rendering process?

While working on creating a basic card view in material UI, I encountered an issue where the functions for adding and deleting items seem to be triggered multiple times upon rendering. I am aware that a common reason for this could be using action={myFunc ...

The Next.js application is unable to load the combined CSS from a React Component Toolkit

My React components repository includes individual .css files for each component which are imported into the respective components. These components are then bundled using a rollup configuration and published as an NPM package, with all component CSS being ...

index signature in TypeScript is an optional feature

Is it possible to create a type with optional namespaces in TypeScript? export interface NodesState { attr1: number; attr2: number; attr3: number; } The goal is to allow users to namespace the type like this: { namespace1: { attr1: 100, ...

Angular - Error: Object returned from response does not match the expected type of 'request?: HttpRequest<any>'

While working on implementing an AuthGuard in Angular, I encountered the following Error: Type 'typeof AuthServiceService' is not assignable to type '(request?: HttpRequest) => string | Promise'. Type 'typeof AuthServiceServic ...

Having trouble with my TinyMCE Editor not loading content data in the Edit.vue component of my Vue 3 project with Vite

I am currently working on a Vue 3 project using Vite and incorporating Editor.vue components with TinyMCE. The code snippet for my Editor.vue component is shown below: My Editor.vue code: <template> <div class="mb-6"> < ...

Error encountered while reading JSON data using Angular4 and TypeScript: Json

When a user selects one or more checkboxes and submits a form, data in the database is updated. At that moment, I call location.reload() from the code to reload the page and display the correct data. Below is the backend web API code: [HttpGet] public as ...