"Enhance your Vue 3 projects with a dynamic library featuring universal components and full

Currently, I am in the process of developing a Vue 3 component library using Vue 3, Vite, and TypeScript. The unique aspect about this library is that it installs as a plugin and registers all components as global entities. Here is an overview of how this process looks:

// src/index.ts
const globalComponents = import.meta.glob("./components/**/*.vue", {
  eager: true,
});

export default {
  install(app: App, options: Record<string, string>) {
    Object.entries(globalComponents).forEach(
      ([item, definition]: [string, any]) => {
        const componentName = item
          ?.split("/")
          ?.pop()
          ?.replace(/\.\w+$/, "");

        app.component(componentName, definition.default);
      }
    );
  },
};

export { /* other exports */ };

In order to build this library, I utilize Vite's Library Mode, which involves the following configuration:

// vite.config.ts
export default defineConfig({
  plugins: [vue()],
  build: {
    target: "esnext",
    lib: {
      formats: ["es"],
      entry: path.resolve(__dirname, "src/index.ts"),
      fileName: (format) => `bundle.${format}.js`,
    },
    rollupOptions: {
      external: [...Object.keys(pkg.dependencies || {})],
    },
  },
});

Furthermore, the build command I use for this project includes the following steps:

vite build && vue-tsc --emitDeclarationOnly && mv dist/src dist/types

This generates a dist directory containing a .d.ts file for each individual component. Despite being able to successfully import the library into various projects, unfortunately, TypeScript support is lacking for the global components.

In my search for a solution, I came across a helpful post on Stack Overflow that suggests adding globals through augmentation:

// src/global-components.d.ts
import Component1 from "@/components/Component1.vue";

declare module "@vue/runtime-core" {
  export interface GlobalComponents {
    Component1: typeof Component1;
  }
}

Although I attempted adding a similar file directly to the library, it did not yield the desired outcome. As a workaround, I included a comparable file in the project and imported each Vue component .d.ts file from the library's dist/types/* directory to provide TypeScript support within the project. While this method works, ideally, I would prefer this functionality to be intrinsic to the library itself.

With that context in mind, my primary question is regarding the implementation of TypeScript support for global components in my library, ensuring its availability to projects utilizing it. If additional details are necessary, please feel free to request them.

Answer №1

My search led me to the original Stack Overflow answer, where I encountered a similar problem. The solution involved replacing

declare module '@vue/runtime-core'
with declare module 'vue'.

This issue arises because many applications do not include @vue/runtime-core, as discussed here and here:

Due to @vue/runtime-core not being installed in multiple projects (especially pnpm projects), the types generated by unplugin-vue-components may not function correctly. With vue already present in Vue projects, augmenting vue is sufficient for the types to work with Volar.

The same approach is outlined in the official Vue documentation on registering web components with TypeScript:

If you are working on an application or library and need to type-check your Vue components, custom elements included, it's essential to register global component typings for Vue templates and/or JSX.

Since custom elements are globally registered using native APIs, they lack type inference when used in Vue templates by default. To enable type support for Vue components registered as custom elements, we can declare global component typings through the GlobalComponents interface in Vue templates or JSX:

import { defineCustomElement } from 'vue'

// Vue Single File Component
import CounterSFC from './src/components/counter.ce.vue'

// Transform component into web components
export const Counter = defineCustomElement(CounterSFC)

// Register global typings
declare module 'vue' {
  export interface GlobalComponents {
    'Counter': typeof Counter,
  }
}

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

Dealing with a nested object problem in Angular using TypeScript

I am currently working on an Angular 15 application that is designed to showcase information about different games to users. Within the application, I have a global object structured like this: GAMES_INFO: { skyroads: { name: 'Sky Roads&a ...

Which RxJS operators necessitate unsubscription?

It can be confusing to know which operators in RxJS must be unsubscribed from to prevent subscription leaks. Some, like forkJoin, complete automatically, while others, such as combineLatest, never complete. Is there a comprehensive list or guideline availa ...

Exploring the various form types supported by 'react-hook-form'

I utilized react hooks form to create this form: import React from "react"; import ReactDOM from "react-dom"; import { useForm, SubmitHandler } from "react-hook-form"; import "./styles.css"; function App() { type ...

In the Show Code feature of Storybook, every element is being displayed for

My Vue 3 + Storybook setup is all running smoothly, except for a little hiccup when I click "Show Code". It seems to display everything instead of just the template. Can anyone help me figure out what's going wrong? https://i.stack.imgur.com/zzBl0.pn ...

Tips for implementing authentication in Vue.js with Azure Active Directory integration

My Vuejs Application needs to be authenticated using a client secret in Azure AD, but I'm having trouble finding any resources on how to do this. ...

What is the best way to transfer data from a clicked table row to another component?

I am currently working on developing an email inbox component for a system where the emails are displayed in a table format. When a user clicks on a specific row, it should lead to another component for further details. Since the information is not rende ...

Tips for Successfully Sending Vue Data in Axios POST Call

I'm struggling to pass Vue data to an axios.post request. Using the Vue template doesn't seem to work. How can I successfully pass the Data? Here is my Code: <body> <div id="app" class="container"> <div> ...

Retrieving the selected option from a dropdown list in VueJS

I have been struggling to store the selected value from a dropdown list as a data object in Vue. Despite my attempts, I am unable to successfully save the value in the Vue data object. I have experimented with using onchange and v-model.lazy, but I am unsu ...

Issue with React TSX component in NextJs 14.0.4: Local MP3 files cannot be played, only external online MP3 files work

I have created a component that wraps around HTML audio and source tags. It functions perfectly when playing mp3 files from an external source, like this sound clip . However, it returns a GET 404 error when trying to access local mp3 files. Can anyone exp ...

Passing data from getServerSideProps to an external component in Next.js using typescript

In my Index.js page, I am using serverSideProps to fetch consumptions data from a mock JSON file and pass it to a component that utilizes DataGrid to display and allow users to modify the values. export const getServerSideProps: GetServerSideProps = async ...

Using useEffect with promises causing TypeScript errors

useEffect(login, []) In this case, the login function returns a promise and the useEffect hook is triggered without expecting a return value. However, TypeScript shows errors like: Argument of type '() => Promise<void>' is not assi ...

Leveraging FormControlName in Typescript to Interact with HTML Components in Angular 4

How can I use FormControlName to access HTML elements in typescript? Typically, I am able to access HTML elements using their ID. For example: var element = document.getElementById("txtID") But is it possible to access the element without using its ID a ...

Retrieve class attributes within callback function

I have integrated the plugin from https://github.com/blinkmobile/cordova-plugin-sketch into my Ionic 3 project. One remaining crucial task is to extract the result from the callback functions so that I can continue working with it. Below is a snippet of ...

Error: `__WEBPACK_IMPORTED_MODULE_1_signature_pad__` does not function as a constructor

I recently discovered the angular2-signature-pad library for capturing signatures in my Angular project. I attempted to integrate the library using the following steps: // in .module.ts file import {SignaturePadModule} from "angular2-signature-pad"; @NgMo ...

Steps to resolve the 'Cannot assign value to userInfo$ property of [object Object] that only has getter' issue in Angular

I am currently in the process of building a web application using NGXS, and I'm encountering a specific error that I'm trying to troubleshoot. The issue arises when I attempt to fetch data from an API and display it within a column on the page. D ...

Issue: Module "mongodb" could not be found when using webpack and typescript

I am encountering an issue while trying to use mongoose with webpack. Even though I have installed it as a dependency, when attempting to utilize the mongoose object and execute commands, it gives me an error stating that it cannot find the "." Module. Thi ...

When using this.$refs in Vue, be mindful that the object may be undefined

After switching to TypeScript, I encountered errors in some of my code related to: Object is possibly 'undefined' The version of TypeScript being used is 3.2.1 Below is the problematic code snippet: this.$refs[`stud-copy-${index}`][0].innerHTM ...

Showcasing diverse content with an Angular Dropdown Menu

I'm currently developing an angular application, and I've encountered a difficulty in displaying the user's selection from a dropdown menu. To elaborate, when a user selects a state like Texas, I want to show information such as the period, ...

The SDK directory for TypeScript 1.3 in Visual Studio 2013 does not include the necessary tsc.exe file

Exciting news! Typescript v1.3 has been officially announced today. To fully utilize this update, I quickly installed the power tools update for VS2013. Upon completion of the installation, my Visual Studio environment now recognizes the "protected" keywo ...

atom-typescript - What could be causing the unrecognized Typescript configuration options?

I'm puzzled as to why I am encountering the errors depicted in the screenshot below. Atom is indicating that my tsconfig.json file has 'project file contains invalid options' for allowJs, buildOnSave, and compileOnSave. However, according ...