天天看點

使用Vite和TypeScript帶你從零打造一個屬于自己的Vue3元件庫

前言

随着前端技術的發展,業界湧現出了許多的UI元件庫。例如我們熟知的ElementUI,Vant,AntDesign等等。但是作為一個前端開發者,你知道一個UI元件庫是如何被打造出來的嗎?

讀完這篇文章你将學會:

  • 如何使用pnpm搭建出一個Monorepo環境
  • 如何使用vite搭建一個基本的Vue3腳手架項目
  • 如何開發調試一個自己的UI元件庫
  • 如何使用vite打包并釋出自己的UI元件庫

作為一個前端擁有一個屬于自己的UI元件庫是一件非常酷的事情。它不僅能讓我們對元件的原理有更深的了解,還能在找工作的時候為自己增色不少。試問有哪個前端不想擁有一套屬于自己的UI元件庫呢?

本文将使用Vue3和TypeScript來編寫一個元件庫,使用Vite+Vue3來對這個元件庫中的元件進行調試,最後使用vite來對元件庫進行打包并且釋出到npm上。最終的産物是一個名為kitty-ui的元件庫。

話不多說~ 接下來讓我們開始搭建屬于我們自己的UI元件庫吧

Monorepo環境

首先我們要了解什麼是Monorepo及它是如何搭建的吧

就是指在一個大的項目倉庫中,管理多個子產品/包(package),這種類型的項目大都在項目根目錄下有一個packages檔案夾,分多個項目管理。大概結構如下:

-- packages
  -- pkg1
    --package.json
  -- pkg2
    --package.json
--package.json
        

簡單來說就是單倉庫 多項目

目前很多我們熟知的項目都是采用這種模式,如Vant,ElementUI,Vue3等。打造一個Monorepo環境的工具有很多,如:lerna、pnpm、yarn等,這裡我們将使用pnpm來開發我們的UI元件庫。

為什麼要使用pnpm?

因為它簡單高效,它沒有太多雜亂的配置,它相比于lerna操作起來友善太多

好了,下面我們就開始用pnpm來進行我們的元件庫搭建吧

使用pnpm

安裝

npm install pnpm -g      

初始化package.json

pnpm init      

建立配置檔案 .npmrc

shamefully-hoist = true      

這裡簡單說下為什麼要配置shamefully-hoist。

如果某些工具僅在根目錄的node_modules時才有效,可以将其設定為true來提升那些不在根目錄的node_modules,就是将你安裝的依賴包的依賴包的依賴包的...都放到同一級别(扁平化)。說白了就是不設定為true有些包就有可能會出問題。

monorepo的實作

接下就是pnpm如何實作monorepo的了。

為了我們各個項目之間能夠互相引用我們要建立一個pnpm-workspace.yaml檔案将我們的包關聯起來

packages:
    - 'packages/**'
    - 'examples'      

這樣就能将我們項目下的packages目錄和examples目錄關聯起來了,當然如果你想關聯更多目錄你隻需要往裡面添加即可。根據上面的目錄結構很顯然你在根目錄下新packages和examples檔案夾,packages檔案夾存放我們開發的包,examples用來調試我們的元件

examples檔案夾就是接下來我們要使用vite搭建一個基本的Vue3腳手架項目的地方

安裝對應依賴

我們開發環境中的依賴一般全部安裝在整個項目根目錄下,友善下面我們每個包都可以引用,是以在安裝的時候需要加個 -w

pnpm i vue@next typescript less -D -w      

因為我們開發的是vue3元件, 是以需要安裝vue3,當然ts肯定是必不可少的(當然如果你想要js開發也是可以的,甚至可以省略到很多配置和寫法。但是ts可以為我們元件加上類型,并且使我們的元件有代碼提示功能,未來ts也将成為主流);less為了我們寫樣式友善,以及使用它的命名空間(這個暫時這裡沒用到,後面有時間再補

  • 配置tsconfig.json

這裡的配置就不細說了,可以自行搜尋都是代表什麼意思。或者你可以先直接複制

npx tsc --init      

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "jsx": "preserve",
    "strict": true,
    "target": "ES2015",
    "module": "ESNext",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "moduleResolution": "Node",
    "lib": ["esnext", "dom"]
  }
}      

手動搭建一個基于vite的vue3項目

其實搭建一個vite+vue3項目是非常容易的,因為vite已經幫我們做了大部分事情

初始化倉庫

進入examples檔案夾,執行

pnpm init      

安裝vite和@vitejs/plugin-vue

@vitejs/plugin-vue用來支援.vue檔案的轉譯

pnpm install vite @vitejs/plugin-vue -D -w      

這裡安裝的插件都放在根目錄下

配置vite.config.ts

建立vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
    plugins:[vue()]
})
      

建立html檔案

@vitejs/plugin-vue 會預設加載examples下的index.html

建立index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
    <script src="main.ts" type="module"></script>
</body>
</html>      

注意:

建立app.vue模闆

<template>
    <div>
        啟動測試
    </div>
</template>      

建立main.ts

import {createApp} from 'vue'
import App from './app.vue'

const app = createApp(App)

app.mount('#app')      

此時會發現編譯器會提示個錯誤:找不到子產品“./app.vue”或其相應的類型聲明

因為直接引入.vue檔案 TS會找不到對應的類型聲明;是以需要建立typings(命名沒有明确規定,TS會自動尋找.d.ts檔案)檔案夾來專門放這些聲明檔案。

typings/vue-shim.d.ts

TypeScriptTS預設隻認ES 子產品。如果你要導入.vue檔案就要declare module把他們聲明出來。

declare module '*.vue' {
    import type { DefineComponent } from "vue";
    const component:DefineComponent<{},{},any>
}      

配置腳本啟動項目

最後在package.json檔案中配置scripts腳本

...
"scripts": {
    "dev": "vite"
  },
...      

然後終端輸入我們熟悉的指令:pnpm run dev

vite啟動預設端口為3000;在浏覽器中打開localhost:3000 就會看我們的“啟動測試”頁面。

本地調試

建立封包件

本節可能和目前元件的開發關聯不大,但是未來元件需要引入一些工具方法的時候會用到

接下來就是要往我們的packages檔案夾沖填充内容了。

  • utils包

一般packages要有utils包來存放我們公共方法,工具函數等

既然它是一個包,是以我們建立utils目錄後就需要初始化它,讓它變成一個包;終端進入utils檔案夾執行:pnpm init 然後會生成一個package.json檔案;這裡需要改一下包名,我這裡将name改成@kitty-ui/utils表示這個utils包是屬于kitty-ui這個組織下的。是以記住釋出之前要登入npm建立一個組織;例如kitty-ui

{
  "name": "@kitty-ui/utils",
  "version": "1.0.0",
  "description": "",
  "main": "index.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
      

因為我們使用ts寫的,是以需要将入口檔案index.js改為index.ts,并建立index.ts檔案:(先導出一個簡單的加法函數)

export const testfun = (a:number,b:number):number=>{
    return a + b
}      
  • 元件庫包(這裡命名為kitty-ui)

components是我們用來存放各種UI元件的包

建立components檔案夾并執行 pnpm init 生成package.json

{
  "name": "kitty-ui",
  "version": "1.0.0",
  "description": "",
  "main": "index.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
      

建立index.ts入口檔案并引入utils包

import {testfun} from '@kitty-ui/utils'

const result = testfun (1,1)

console.log(result)      
  • esno

由于元件庫是基于ts的,是以需要安裝esno來執行ts檔案便于測試元件之間的引入情況

控制台輸入esno xxx.ts即可執行ts檔案

npm i esno -g      

包之間本地調試

進入components檔案夾執行

pnpm install @kitty-ui/utils      

你會發現pnpm會自動建立個軟連結直接指向我們的utils包;此時components下的packages:

{
  "name": "kitty-ui",
  "version": "1.0.0",
  "description": "",
  "main": "src/index.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@kitty-ui/utils": "workspace:^1.0.1"
  }
}
      

你會發現它的依賴@kitty-ui/utils對應的版本為:workspace:^1.0.0;因為pnpm是由workspace管理的,是以有一個字首workspace可以指向utils下的工作空間進而友善本地調試各個包直接的關聯引用。

到這裡基本開發方法我們已經知道啦;接下來就要進入正題了,開發一個button元件

試着開發一個button元件

在components檔案夾下建立src,同時在src下建立button元件目錄和icon元件目錄(建立icon為了便于調試);此時components檔案目錄如下

-- components
  -- src
    -- button
    -- icon
    -- index.ts
-- package.json
      

讓我們先測試一下我們的button元件能否在我們搭建的examples下的vue3項目本引用~

首先在button下建立一個簡單的button.vue

<template>
    <button>測試按鈕</button>
</template>      

然後在button/index.ts将其導出

import Button from './button.vue'

export default Button      

因為我們開發元件庫的時候不可能隻有button,是以我們需要一個components/index.ts将我們開發的元件一個個的集中導出

import Button from './button'

export {
    Button
}
      

好了,一個元件的大體目錄差不多就是這樣了,接下來請進入我們的examples來看看能否引入我們的button元件

vue3項目使用button

上面已經說過執行在workspace執行 pnpm i xxx的時候pnpm會自動建立個軟連結直接指向我們的xxx包。

是以這裡我們直接在examples執行:pnpm i kitty-ui

此時你就會發現packages.json的依賴多了個

"kitty-ui": "workspace:^1.0.0"      

這時候我們就能直接在我們的測試項目下引入我們本地的components元件庫了,啟動我們的測試項目,來到我們的 examples/app.vue 直接引入Button

<template>
    <div>
        <Button />
    </div>
</template>
<script lang="ts" setup>
import { Button } from 'kitty-ui'
</script>      

不出意外的話你的頁面就會展示我們剛剛寫的button元件了

好了萬事具...(其實還差個打包,這個後面再說~);接下來的工作就是專注于元件的開發了;讓我們回到我們的button元件目錄下(測試頁面不用關,此時我們已經可以邊開發邊調試邊看效果了)

因為我們的button元件是需要接收很多屬性的,如type、size等等,是以我們要建立個types.ts檔案來規範這些屬性

在button目錄下建立types.ts

import { ExtractPropTypes } from 'vue'


export const ButtonType = ['default', 'primary', 'success', 'warning', 'danger']

export const ButtonSize = ['large', 'normal', 'small', 'mini'];


export const buttonProps = {
  type: {
    type: String,
    values: ButtonType
  },
  size: {
    type: String,
    values: ButtonSize
  }
}

export type ButtonProps = ExtractPropTypes<typeof buttonProps>






      

TIPS

import type 表示隻導入類型;ExtractPropTypes是vue3中内置的類型聲明,它的作用是接收一個類型,然後把對應的vue3所接收的props類型提供出來,後面有需要可以直接使用

很多時候我們在vue中使用一個元件會用的app.use 将元件挂載到全局。要使用app.use函數的話我們需要讓我們的每個元件都提供一個install方法,app.use()的時候就會調用這個方法;

我們将button/index.ts調整為

import button from './button.vue'
import type {App,Plugin} from "vue"
type SFCWithInstall<T> = T&Plugin
const withInstall = <T>(comp:T) => {
    (comp as SFCWithInstall<T>).install = (app:App)=>{
        //注冊元件
        app.component((comp as any).name,comp)
    }
    return comp as SFCWithInstall<T>
}
const Button = withInstall(button)
export default Button      

此時我們就可以使用app.use來挂載我們的元件啦

其實withInstall方法可以做個公共方法放到工具庫裡,因為後續每個元件都會用到,這裡等後面開發元件的時候再調整

到這裡元件開發的基本配置已經完成,最後我們對我們的元件庫以及工具庫進行打包,打包之前如果要發公共包的話記得将我們的各個包的協定改為MIT開源協定

...
"license": "MIT",
...      

vite打包

配置檔案

打包們這裡選擇vite,它有一個庫模式專門為我們來打包這種庫元件的。

前面已經安裝過vite了,是以這裡直接在components下直接建立vite.config.ts(配置參數檔案中已經注釋):

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"
export default defineConfig(
    {
        build: {
            target: 'modules',
            //打封包件目錄
            outDir: "es",
            //壓縮
            minify: false,
            //css分離
            //cssCodeSplit: true,
            rollupOptions: {
                //忽略打包vue檔案
                external: ['vue'],
                input: ['src/index.ts'],
                output: [
                    {
                        format: 'es',
                        //不用打包成.es.js,這裡我們想把它打包成.js
                        entryFileNames: '[name].js',
                        //讓打包目錄和我們目錄對應
                        preserveModules: true,
                        //配置打包根目錄
                        dir: 'es',
                        preserveModulesRoot: 'src'
                    },
                    {
                        format: 'cjs',
                        entryFileNames: '[name].js',
                        //讓打包目錄和我們目錄對應
                        preserveModules: true,
                        //配置打包根目錄
                        dir: 'lib',
                        preserveModulesRoot: 'src'
                    }
                ]
            },
            lib: {
                entry: './index.ts',
                formats: ['es', 'cjs']
            }
        },
        plugins: [
            vue()
        ]
    }
)
      

這裡我們選擇打包cjs(CommonJS)和esm(ESModule)兩種形式,cjs模式主要用于服務端引用(ssr),而esm就是我們現在經常使用的方式,它本身自帶treeShaking而不需要額外配置按需引入(前提是你将子產品分别導出),非常好用~

其實到這裡就已經可以直接打包了;components下執行: pnpm run build你就會發現打包了es和lib兩個目錄

使用Vite和TypeScript帶你從零打造一個屬于自己的Vue3元件庫

到這裡其實打包的元件庫隻能給js項目使用,在ts項目下運作會出現一些錯誤,而且使用的時候還會失去代碼提示功能,這樣的話我們就失去了用ts開發元件庫的意義了。是以我們需要在打包的庫裡加入聲明檔案(.d.ts)。

那麼如何向打包後的庫裡加入聲明檔案呢? 其實很簡單,隻需要引入vite-plugin-dts

pnpm i vite-plugin-dts -D -w      

然後修改一下我們的vite.config.ts引入這個插件

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"
import dts from 'vite-plugin-dts'

export default defineConfig(
    {
        build: {...},
        plugins: [
            vue(),
            dts({
                //指定使用的tsconfig.json為我們整個項目根目錄下掉,如果不配置,你也可以在components下建立tsconfig.json
                tsConfigFilePath: '../../tsconfig.json'
            }),
            //因為這個插件預設打包到es下,我們想讓lib目錄下也生成聲明檔案需要再配置一個
            dts({
                outputDir:'lib',
                tsConfigFilePath: '../../tsconfig.json'
            })

        ]
    }
)      

因為這個插件預設打包到es下,我們想讓lib目錄下也生成聲明檔案需要再配置一個dts插件,暫時沒有想到其它更好的處理方法~

然後執行打包指令你就會發現你的es和lib下就有了聲明檔案

其實後面就可以進行釋出了,釋出之前更改一下我們components下的package.json如下:

{
  "name": "kitty-ui",
  "version": "1.0.0",
  "main": "lib/index.js",
  "module":"es/index.js",
  "scripts": {
    "build": "vite build"
  },
  "files": [
    "es",
    "lib"
  ],
  "keywords": [
    "kitty-ui",
    "vue3元件庫"
  ],
  "author": "小月",
  "license": "MIT",
  "description": "",
  "typings": "lib/index.d.ts"
}
      

解釋一下裡面部分字段

pkg.module

我們元件庫預設入口檔案是傳統的CommonJS子產品,但是如果你的環境支援ESModule的話,建構工具會優先使用我們的module入口

pkg.files

files是指我們1需要釋出到npm上的目錄,因為不可能components下的所有目錄都被釋出上去

開始釋出

如果打包和釋出流程你想做到自動化控制,你可以先點個贊,然後直接閱讀 ​​從0搭建Vue3元件庫:使用gulp自動化處理打包與釋出​​ 當然你也可以繼續往下閱讀,看下本篇文章的處理方式

做了那麼多終于到釋出的階段了;其實npm發包是很容易的,就拿我們的元件庫kitty-ui舉例吧

釋出之前記得到​​npm​​官網注冊個賬戶,如果你要釋出@xx/xx這種包的話需要在npm建立個組織組織組織名就是@後面的,比如我建的組織就是kitty-ui,注冊完之後你就可以釋出了

首先要将我們代碼送出到git倉庫,不然pnpm釋出無法通過,後面每次發版記得在對應包下執行 pnpm version patch你就會發現這個包的版本号patch(版本号第三個數) +1 了,同樣的 pnpm version major major和 pnpm version minor 分别對應版本号的第一和第二位增加。

如果你釋出的是公共包的話,在對應包下執行

pnpm publish --access public      

輸入你的賬戶和密碼(記得輸入密碼的時候是不顯示的,不要以為卡了)正常情況下應該是釋出成功了

注意

釋出的時候要将npm的源切換到npm的官方位址(​​https://registry.npmjs.org/​​); 如果你使用了其它鏡像源的話

樣式問題

引入我們打包後的元件你會發現沒有樣式,是以你需要在全局引入我們的style.css才行;如 main.ts中需要

import 'kitty-ui/es/style.css';      

很顯然這種元件庫并不是我們想要的,我們需要的元件庫是每個css樣式放在每個元件其對應目錄下,這樣就不需要每次都全量導入我們的css樣式。

下面就讓我們來看下如何把樣式拆分打包

處理less檔案

首先我們需要做的是将less打包成css然後放到打包後對應的檔案目錄下,我們在components下建立build檔案夾來存放我們的一些打包工具,然後建立buildLess.ts,首先我們需要先安裝一些工具cpy和fast-glob

pnpm i cpy fast-glob -D -w      
  • cpy

它可以直接複制我們規定的檔案并将我們的檔案copy到指定目錄,比如buildLess.ts:

import cpy from 'cpy'
import { resolve } from 'path'

const sourceDir = resolve(__dirname, '../src')
//lib檔案
const targetLib = resolve(__dirname, '../lib')
//es檔案
const targetEs = resolve(__dirname, '../es')
console.log(sourceDir);
const buildLess = async () => {
    await cpy(`${sourceDir}/**/*.less`, targetLib)
    await cpy(`${sourceDir}/**/*.less`, targetEs)
}
buildLess()
      

然後在package.json中新增指令

...
"scripts": {
    "build": "vite build",
    "build:less": "esno build/buildLess"
  },
...      

終端執行 pnpm run build:less 你就會發現lib和es檔案對應目錄下就出現了less檔案.

但是我們最終要的并不是less檔案而是css檔案,是以我們要将less打包成css,是以我們需要用的less子產品.在ts中引入less因為它本身沒有聲明檔案是以會出現類型錯誤,是以我們要先安裝它的 @types/less

pnpm i --save-dev @types/less -D -w      

buildLess.ts如下(詳細注釋都在代碼中)

import cpy from 'cpy'
import { resolve, dirname } from 'path'
import { promises as fs } from "fs"
import less from "less"
import glob from "fast-glob"
const sourceDir = resolve(__dirname, '../src')
//lib檔案目錄
const targetLib = resolve(__dirname, '../lib')
//es檔案目錄
const targetEs = resolve(__dirname, '../es')

//src目錄

const srcDir = resolve(__dirname, '../src')

const buildLess = async () => {
    //直接将less檔案複制到打包後目錄
    await cpy(`${sourceDir}/**/*.less`, targetLib)
    await cpy(`${sourceDir}/**/*.less`, targetEs)

    //擷取打包後.less檔案目錄(lib和es一樣)
    const lessFils = await glob("**/*.less", { cwd: srcDir, onlyFiles: true })

    //周遊含有less的目錄
    for (let path in lessFils) {

        const filePath = `${srcDir}/${lessFils[path]}`
        //擷取less檔案字元串
        const lessCode = await fs.readFile(filePath, 'utf-8')
        //将less解析成css

        const code = await less.render(lessCode, {
            //指定src下對應less檔案的檔案夾為目錄
            paths: [srcDir, dirname(filePath)]
        })

        //拿到.css字尾path
        const cssPath = lessFils[path].replace('.less', '.css')


        //将css寫入對應目錄
        await fs.writeFile(resolve(targetLib, cssPath), code.css)
        await fs.writeFile(resolve(targetEs, cssPath), code.css)
    }



}
buildLess()



      

執行打包指令之後你會發現對應檔案夾下多了.css檔案

使用Vite和TypeScript帶你從零打造一個屬于自己的Vue3元件庫

現在我已經将css檔案放入對應的目錄下了,但是我們的相關元件并沒有引入這個css檔案;是以我們需要的是每個打包後元件的index.js中出現如:

import "xxx/xxx.css"      

之類的代碼我們的css才會生效;是以我們需要對vite.config.ts進行相關配置

首先我們先将.less檔案忽略

external: ['vue', /\.less/],      

這時候打包後的檔案中如button/index.js就會出現

import "./style/index.less";      

然後我們再将打包後代碼的.less換成.css就大功告成了

...
plugins: [
            ...

            {
                name: 'style',
                generateBundle(config, bundle) {
                    //這裡可以擷取打包後的檔案目錄以及代碼code
                    const keys = Object.keys(bundle)

                    for (const key of keys) {
                        const bundler: any = bundle[key as any]
                        //rollup内置方法,将所有輸出檔案code中的.less換成.css,因為我們當時沒有打包less檔案

                        this.emitFile({
                            type: 'asset',
                            fileName: key,//檔案名名不變
                            source: bundler.code.replace(/\.less/g, '.css')
                        })
                    }
                }
            }
        ...
        ]
...      

我們最終的vite.config.ts如下

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue"
import dts from 'vite-plugin-dts'

export default defineConfig(
    {
        build: {
            target: 'modules',
            //打封包件目錄
            outDir: "es",
            //壓縮
            minify: false,
            //css分離
            //cssCodeSplit: true,
            rollupOptions: {
                //忽略打包vue和.less檔案
                external: ['vue', /\.less/],
                input: ['src/index.ts'],
                output: [
                    {
                        format: 'es',
                        //不用打包成.es.js,這裡我們想把它打包成.js
                        entryFileNames: '[name].js',
                        //讓打包目錄和我們目錄對應
                        preserveModules: true,
                        //配置打包根目錄
                        dir: 'es',
                        preserveModulesRoot: 'src'
                    },
                    {
                        format: 'cjs',
                        //不用打包成.mjs
                        entryFileNames: '[name].js',
                        //讓打包目錄和我們目錄對應
                        preserveModules: true,
                        //配置打包根目錄
                        dir: 'lib',
                        preserveModulesRoot: 'src'
                    }
                ]
            },
            lib: {
                entry: './index.ts',
                formats: ['es', 'cjs']
            }
        },




        plugins: [
            vue(),
            dts({
                //指定使用的tsconfig.json為我們整個項目根目錄下掉,如果不配置,你也可以在components下建立tsconfig.json
                tsConfigFilePath: '../../tsconfig.json'
            }),
            //因為這個插件預設打包到es下,我們想讓lib目錄下也生成聲明檔案需要再配置一個
            dts({
                outputDir: 'lib',
                tsConfigFilePath: '../../tsconfig.json'
            }),

            {
                name: 'style',
                generateBundle(config, bundle) {
                    //這裡可以擷取打包後的檔案目錄以及代碼code
                    const keys = Object.keys(bundle)

                    for (const key of keys) {
                        const bundler: any = bundle[key as any]
                        //rollup内置方法,将所有輸出檔案code中的.less換成.css,因為我們當時沒有打包less檔案

                        this.emitFile({
                            type: 'asset',
                            fileName: key,//檔案名名不變
                            source: bundler.code.replace(/\.less/g, '.css')
                        })
                    }
                }
            }

        ]
    }
)
      

最後我們将打包less與打包元件合成一個指令(package.json):

...
"scripts": {
    "build": "vite build & esno build/buildLess"
  },
...      

後續直接執行pnpm run build 即可完成所有打包啦

直接使用

如果你不想一步步的搭建,想直接使用現成的話,你可以直接把項目clone下來->​​kittyui第一版​​,然後你隻需要以下幾步便可将其完成

  • 安裝pnpm

    npm i pnpm -g

  • 安裝esno

    npm i esno -g

  • 安裝所有依賴

    pnpm install

  • 本地測試

    進入examples檔案夾執行 pnpm run dev 啟動vue3項目

  • 打包

    pnpm run build

寫在最後

由于作者水準有限,難免會存在一些錯誤或不妥之處,希望各位能夠不吝指出,一定及時修改。如果你對這個項目有更好的想法或者建議也歡迎在評論區提出,不勝感激。