Building Vue3 Component Library from Scratch #5 Use Vite to Package Your Component Library
Tags: vite, vue
Published: 2024-05-23 03:48:45

This article will introduce how to use Vite to package our component library, and also explain how to use plugins to automatically generate declaration files (*.d.ts) for the packaged files.

## Packaging Configuration

Vite specifically provides a packaging method for library mode, and the configuration is actually very simple. First, globally install Vite and @vitejs/plugin-vue.

```bash
pnpm add vite @vitejs/plugin-vue -D -w
```

Create vite.config.ts configuration file under the components directory.

```typescript
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
  build: {
    outDir: "es",
    minify: false,
    rollupOptions: {
      external: ["vue"],
      //input: ["index.ts"],
      output: {
        globals: {
          vue: "Vue",
        },
        dir: "dist",
      },
    },
    lib: {
      entry: "./index.ts",
      name: "stellarnovaui",
      fileName: "stellarnovaui",
      formats: ["es", "umd", "cjs"],
    },
  },
  plugins: [vue()],
});
```

Then add build command in components/package.json.

```json
"scripts": {
  "build": "vite build"
},
```

Run `pnpm run build`，check the dist folder.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/upnf92a9sfhxet3gg9np.png)

However, this way of package will eventually package the entire component library into a single file, and the style files cannot be loaded on demand. Therefore, we need to modify the configuration to make the packaged structure consistent with our development structure. In the following configuration, we will place the packaged files in 'stellarnovaui' directory, as the name of the component library we will publish later is 'stellarnovaui'. Of course, you can name it whatever you like.

```typescript
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
export default defineConfig({
  build: {
    outDir: "es",
    //minify: false,
    rollupOptions: {
      external: ["vue"],
      input: ["index.ts"],
      output: [
        {
          format: "es",
          entryFileNames: "[name].mjs",
          preserveModules: true,
          exports: "named",
          dir: "../stellarnovaui/es",
        },
        {
          format: "cjs",
          entryFileNames: "[name].js",
          preserveModules: true,
          exports: "named",
          dir: "../stellarnovaui/lib",
        },
      ],
    },
    lib: {
      entry: "./index.ts",
    },
  },
  plugins: [vue()],
});
```

run `pnpm run build` again. Checkout folder `stellarnovaui`, the build output file is the same structure with our component folder.

However, at this point, all style files will still be packaged together into style.css, so we still can't load styles on demand. Therefore, next we will configure Vite to not package the style files, and instead package the style files separately later.

## Declaration Files

At this point, the packaged component library can only be used in JavaScript projects. Running it in TypeScript projects will cause some errors, and code hints will be lost when using it. This negates the purpose of using TypeScript to develop the component library. Therefore, we need to include declaration files (.d.ts) in the packaged library.

Install vite-plugin-dts, and make sure the version is consistent.

```bash
pnpm add vite-plugin-dts@1.4.1 -D -w
```

Import it into vite.config.ts. Note that we also add the component naming plugin DefineOptions here (mentioned in the previous article). Be sure to write this after dts, as there might be errors in the source code.

```typescript
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";
import DefineOptions from "unplugin-vue-define-options/vite";
export default defineConfig({
  plugins: [
    vue(),
    dts({
      entryRoot: "./src",
      outputDir: ["../stellarnovaui/es/src", "../stellarnovaui/lib/src"],
      tsConfigFilePath: "../../tsconfig.json",
    }),
    DefineOptions(),
  ],
});
```

After packaging again, you will find that the declaration files we need have appeared in the packaged files.

Actually, most front-end build scaffolds now support ES modules, which inherently support on-demand loading. Therefore, the ES format of the packaged component library comes with tree shaking by default, and does not require additional configuration for on-demand imports. Next, we will make the style files support on-demand imports as well. Stay tuned.

The final source code: https://github.com/markliu2013/StellarNovaUI

For more information about build your component library, checkout this article, https://dev.to/markliu2013/how-to-build-component-libraries-8k2