A situation that tends to happen when working on multiple projects is that the same generic components are needed on each individual project like a stylized text field or something a little bit more complex like a date picker.
The best course of action would be to write the component once and update it from a single point, that being the package where it's being distributed from.
What we'll be doing is writing an NPM package that exports a Vue 3 component with TypeScript type definitions to boot! The component I've chosen to make is a tri-state checkbox for this demonstration.
I'll be using Vite for this project since it is a nice alternative to webpack as a build tool and development server. Use your package manager of choice to create a project, I'll go with
yarn
:
yarn create vite
Choose these settings and name your project ideally how you would name your final component:
√ Project name: ... vue-tri-state-checkbox
√ Select a framework: » Vue
√ Select a variant: » TypeScript
Purge the project of any files or code you don't need, I usually just use App.vue for testing purposes with the components folder being used to store the components and export them.
Your src folder should look like this:
Write your component as you would usually with regards to how Vue 3 works, I am going to use this as an example for my component:
Let's go over what's going on here: first off, inside the plugins property we added dts which is part of the vite-plugin-dts package. Its main purpose is creating type definition files from vue files automatically for better development experience, that is to say it create d.ts files from .vue ones.
Inside the build property we have defined some additional properties which will be used for defining how the build process of the package itself should work.
lib tells the build process to treat the entire thing like an exportable library, read more here. The properties we define here are:
entry - where the package export is, that is to say where the user will import the package from after publishing it, here we point the entry to the previously defined index.ts folder inside src using the path function and the __dirname variable which points to the main folder of the project
name - a unique identifier of the package, try to keep this in line with your package name
fileName - a unique identifier which will be used to describe the package file output
Inside rollupOptions we will define a few things to tell Rollup how to configure the module bundler:
external - a definition of any external dependencides needed to run the package, in this case vue itself, read more hereoutput.globals - needed to provide context to the used external dependencies, read more here
Finally, the resolve property is used to make development easier with defining the @ as an alias to the src folder path.
Next we'll be editing the tsconfig.json file: "compilerOptions":{"target":"ESNext","useDefineForClassFields":true,"module":"ESNext","moduleResolution":"Node","strict":true,"jsx":"preserve","resolveJsonModule":true,"isolatedModules":true,"esModuleInterop":true,"lib":["ESNext","DOM"],"skipLibCheck":true,"noEmit":true"include":["src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.vue"],"references":[{"path":"./tsconfig.node.json"}]Enter fullscreen modeExit fullscreen mode
When you're all done editing the previously mentioned files, we need to see if the build process works by running yarn build.
You should get an output similar to this:
$ vue-tsc && vite build
vite v4.3.9 building for production...
✓ 4 modules transformed.
dist/style.css 2.15 kB │ gzip: 0.65 kB
dist/vue-tri-state-checkbox.js 1.12 kB │ gzip: 0.58 kB
dist/vue-tri-state-checkbox.umd.cjs 1.09 kB │ gzip: 0.61 kB
[vite:dts] Start generate declaration files...
✓ built in 1.29s
[vite:dts] Declaration files built in 822ms.
Done in 3.49s.
Enter fullscreen modeExit fullscreen modestyle.css - the CSS of the package bundled inside a singular entry point
vue-tri-state-checkbox.js - main package entry point which contains the bundled JavaScript code
vue-tri-state-checkbox.umd.cjs - universal module system and common js entry point
index.d.ts - generated type definitions
All of these are located inside the dist folder which will be used to distribute the package with NPM.
Before we do that though, we have to edit package.json.
package.json
We will need to alter package.json in order to distribute the newly created component (the words component and package will be used interchangeably from now on):
private needs to be set to false
add a files property to specify which files will play a role in how the package functions, after building the component with yarn build all of the distribution files will be inside the dist folder
"files": ["dist", "src/components/"],
Enter fullscreen modeExit fullscreen mode
Additionally, we will be adding the src/components folder because the components are exported from there.
name your GIT repository inside the repository property
Enter fullscreen modeExit fullscreen mode<scriptlang="ts"setup>import { ref } from"vue";import { TriStateCheckbox } from"vue-tri-state-checkbox";import"vue-tri-state-checkbox/dist/style.css";const val =ref(null);</script>
Enter fullscreen modeExit fullscreen mode
Modular and scalable Front End architecture 🗃️
Experienced 💻 Javascript Developer
Master & Vue.js Lover 💘
Vue Consultant 👨🏫
Modular and scalable Front End architecture 🗃️
Experienced 💻 Javascript Developer
Master & Vue.js Lover 💘
Vue Consultant 👨🏫
Once unpublished, all posts by matijanovosel will become hidden and only accessible to themselves.
If matijanovosel is not suspended, they can still re-publish their posts from their dashboard.