DEV Community

Mark
Mark

Posted on • Updated on

Building Vue3 Component Library from Scratch #5 Use Vite to Package Your Component Library

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.

pnpm add vite @vitejs/plugin-vue -D -w
Enter fullscreen mode Exit fullscreen mode

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

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()],
});
Enter fullscreen mode Exit fullscreen mode

Then add build command in components/package.json.

"scripts": {
  "build": "vite build"
},
Enter fullscreen mode Exit fullscreen mode

Run pnpm run build,check the dist folder.

Image description

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.

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()],
});
Enter fullscreen mode Exit fullscreen mode

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.

pnpm add vite-plugin-dts@1.4.1 -D -w
Enter fullscreen mode Exit fullscreen mode

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.

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(),
  ],
});
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)