The ultimate guide for building Vue 3 component libraries in 2023
by Patrick Russ
In the fast-paced world of web development, building reusable components can be a game-changer. Fortunately, Vue 3 and Vite have emerged as powerful tools that simplify the process of creating component libraries. In this tutorial, we'll take a closer look at how to build such a library. This will empower you to create efficient, modular, and shareable UI components. For our demonstration, we'll create a simple reusable button component that looks like this:
Prerequisites
Before diving into the tutorial, make sure you have Node.js installed. If you don't have it yet, you can find the installation instructions on the official website.
1. Set up your project
Let's kick things off by creating a new Vue 3 project using Vite. Open your terminal and run the following command:
npm create vite@latest
During project setup, you'll have the option to choose various configurations. We recommend selecting TypeScript and ESLint for better type safety and code quality. However, feel free to pick the options that suit your needs best. Once the project is created, navigate to the project directory and install the dependencies:
cd <project-name>
npm install
2. Create your first component
With your project all set up, it's time to create your very first Vue 3 component. Inside the src/components
directory,
create a new file named ReusableButton.vue
. Here's what the code for this simple button component looks like:
<script setup lang="ts">
</script>
<template>
<button class="button" type="button">
<slot></slot>
</button>
</template>
<style scoped>
.button {
cursor: pointer;
background-color: #555555;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 6px;
}
.button:hover {
background-color: #444444;
}
</style>
This code defines a styled button component with a slot for custom content. If you need a refresher on how to create robust Vue 3 components, you can check out this blog post.
3. Build your component library
To use your component library in other projects, you need to build it first. Vite makes this process straightforward with just a few configuration tweaks. Here are the files you need to change or add:
vite.config.ts
Update your vite.config.ts
file as follows:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
],
build: {
cssCodeSplit: true,
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'component-library', // adapt to your library name
fileName: 'component-library' // adapt to your library name
},
rollupOptions: {
external: ['vue'],
output: {
exports: 'named',
globals: {
vue: 'Vue'
}
}
}
},
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
This configuration tells Vite how to handle your component library during development and the build process. Notably, the
external
option excludes Vue from the bundle since it will be provided by the consuming application. The
resolve.alias
option is used to resolve the @
alias, which can be used in the component library to import other components.
tsconfig.json
Update your tsconfig.json
file as follows:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"outDir": "dist",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true
},
"exclude": ["src/App.vue", "src/main.ts"],
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "src/index.ts"]
}
This instructs TypeScript to
- Output the declaration files and source maps to the
dist
directory. - Use the
@
alias to resolve imports. - Exclude the
src/App.vue
andsrc/main.ts
files from the build process.
You can safely delete the tsconfig.node.json
and tsconfig.app.json
files which were created during the project setup.
index.ts
Create an index.ts
file inside your src
directory. This file serves as the entry point of your
component library, making all components and other files exported here available to the consuming application:
export { default as ReusableButton } from '@/components/ReusableButton.vue'
package.json
Finally, update or add the following sections in your package.json
:
...
"scripts": {
"dev": "vite",
"build": "run-p type-check build-only",
"preview": "vite preview",
"build-only": "vite build",
"type-check": "vue-tsc --emitDeclarationOnly && tsc-alias -p tsconfig.json",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
},
"type": "module",
"files": [
"dist"
],
"main": "./dist/component-library.umd.cjs",
"module": "./dist/component-library.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/component-library.js",
"require": "./dist/component-library.umd.cjs"
},
"./index.css": "./dist/index.css"
},
"types": "./dist/index.d.ts",
...
For the tsc-alias command, which resolves aliases during the build process, make sure to install the tsc-alias package. Otherwise, the consuming application will not be able to correctly resolve the type definitions.
npm install --save-dev tsc-alias
With everything set up, you can now build your component library by running:
npm run build
The output will be placed in the dist
directory.
4. Publish your component library
To share your component library with others, consider publishing it to a package registry like npm. First, ensure you have an npm account, and then run the following commands:
npm login
npm publish
5. Consume your component library
Now that your component library is published, you can consume it in other projects. Either install it via npm or by using
a file path ("component-library": "file:../component-library"
, make sure to double-check the location). Then, import the components you need and use them in
your application. Don't forget to import the index.css
file as well.
<script setup lang="ts">
import { ReusableButton } from 'component-library'
import 'component-library/index.css'
</script>
<template>
<ReusableButton>Click me</ReusableButton>
</template>
Congrats! You've successfully created, published and consumed your first Vue 3 component library!
Conclusion
Building a Vue 3 component library using Vite streamlines the process of creating and sharing reusable UI components. By following the steps outlined in this tutorial, you've learned how to create, register, and distribute your Vue components, enabling you to contribute to the Vue ecosystem and simplify development across multiple projects.
Source code
You can find the complete source code of the component library on GitHub.
If you need help with your Vue 3 component library or any other project, feel free to contact us for consultation.