使用 Vite+TypeScript 打造一个 Vue3 组件库

使用 Vite+TypeScript 打造一个 Vue3 组件库

文章目录

  • 使用 Vite+TypeScript 打造一个 Vue3 组件库
    • 写在前面
    • 搭建 Monorepo 环境
      • 什么是 Monorepo 环境
      • 使用 pnpm
        • 安装
        • 初始化 package.json
        • 新建配置文件 .npmrc
      • monorepo 的实现
      • 安装对应依赖
    • 搭建一个基于 vite 的 vue3 项目
      • 初始化仓库
      • 安装 vite 和 @vitejs/plugin-vue
      • 配置 vite.config.ts
      • 新建 html 文件
      • 新建 app.vue 模板
      • 新建 main.ts
      • 配置脚本启动项目
    • 本地调试
      • 新建包文件
        • utils 包
        • karl-ui 组件库包
        • esno
      • 包之间本地调试
    • 试着开发一个 button 组件
    • vue3 项目使用 button 组件
    • vite打包
      • 配置文件
    • 样式问题
      • 处理less文件
      • cpy
      • 引入 css 文件
  • 引入单元测试框架Vitest
    • 安装与配置
      • 安装
      • 配置
    • 测试组件
      • 测试 slot
      • 测试 type
    • 查看测试覆盖率
    • 快速搭建教程
      • 下载脚手架
      • 安装 pnpm
      • 安装模板
      • 安装依赖
      • 开始开发组件库
      • 查看效果
    • 写在最后

写在前面

其实这是我第一次搭建组件库时写的笔记,但是完成后和最终项目还是有所差异,但是按这个项目确实可以跑,就只是没有配一些 eslintstylelintcommit 规范等。
作者目前是在参加某节的青训营,然后要完成一个大项目,我们团队选了组件库的搭建。

现在有两个好消息:

  1. 第一个好消息翻到最后一个部分,有惊喜
  2. 作者目前正在写组件库文档的教程,完成组件库后可以观看【vitepress 最详细教程之开始使用】开始创建一个属于自己的文档吧 ,正在更新中

搭建 Monorepo 环境

什么是 Monorepo 环境

就是指在一个大的项目仓库中,管理多个模块/包(package),这种类型的项目大都在项目根目录下有一个packages文件夹,分多个项目管理。大概结构如下:

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

简单来说就是单仓库 多项目,目前 Vant,ElementUI,Vue3 等项目都是采用这种模式。打造一个Monorepo环境的工具有很多,如:lerna、pnpm、yarn等,这里我们将使用 pnpm 来开发我们的UI组件库

使用 pnpm

安装
npm install pnpm -g

如果出现以下报错信息:

npm ERR! code EACCES
npm ERR! syscall mkdir
npm ERR! path /usr/local/lib/node_modules/pnpm
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/pnpm'
npm ERR!  [Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/pnpm'] {
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'mkdir',
npm ERR!   path: '/usr/local/lib/node_modules/pnpm'
npm ERR! }
npm ERR! 
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR! 
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/xxx/.npm/_logs/2023-01-14T03_24_24_270Z-debug-0.log

✅ 解决方法是使用管理员权限安装,即使用 sudo npm install pnpm -g

初始化 package.json
pnpm init
新建配置文件 .npmrc
shamefully-hoist = true

默认情况下 pnpm 安装的依赖是会解决幽灵依赖的问题,所谓什么是幽灵依赖你可以查看**这篇文章**。

文件名就叫 .npmrc

如果某些工具仅在根目录的 node_modules 时才有效,可以将其设置为 true 来提升那些不在根目录的 node_modules,就是将你安装的依赖包的依赖包的依赖包都放到同一级别(扁平化),说白了就是不设置为 true 有些包就有可能会出问题

monorepo 的实现

「根目录」 下新建一个 pnpm-workspace.yaml 文件,内容如下:

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

如果想关联更多目录你只需要往里面添加即可,packages 文件夹存放开发的包,examples 用来调试组件

安装对应依赖

开发环境中的依赖一般全部安装在整个项目根目录下,方便每个包都可以引用,所以在安装的时候需要加个 -w

pnpm i vue@next typescript less -D -w

上面的命令是安装 vue3、TypeScript、Less

如果出现以下问题:

 ERROR  --workspace-root may only be used inside a workspace

✅ 解决方法是新建一个 pnpm-workspace.yaml 文件

如果安装了 TypeScript 那么需要在 「根目录」 下新建一个 tsconfig.json 文件,内容如下:

{
  "compilerOptions": {
    "baseUrl": ".",
    "jsx": "preserve", // jsx 不转
    "strict": true,
    "target": "ES2015", // 遵循es5版本
    "module": "ESNext", // 打包模块类型ESNext
    "skipLibCheck": true, // 跳过类库检测
    "esModuleInterop": true, // 支持es6,commonjs模块
    "moduleResolution": "Node", // 按照node模块来解析
    "lib": ["esnext", "dom"] // 编译时用的库
  }
}

你可以使用命令 npx tsc --init 新建一个配置文件,也可以手动新建一个

搭建一个基于 vite 的 vue3 项目

vite 已经帮我们做了大部分事情

初始化仓库

进入 examples 文件夹:

cd examples

初始化配置:

pnpm init

安装 vite 和 @vitejs/plugin-vue

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

@vitejs/plugin-vue 用来支持 .vue 文件的转译,这里安装的插件都放在 「根目录」

也就是根目录下的 package.json 文件是这样的:

{
  ......
  "devDependencies": {
    ......
    "@vitejs/plugin-vue": "^4.0.0",
    "vite": "^4.0.4",
  }
}

配置 vite.config.ts

examples 文件夹下新建 vite.config.ts 文件

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

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

新建 html 文件

examples 文件夹下新建 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>Documenttitle>
head>

<body>
  <div id="app">div>
  <script src="main.ts" type="module">script>
body>

html>

⚠️ @vitejs/plugin-vue 会默认加载 examples 下的 index.html,vite 是基于 esmodule 的,所以要在 script 标签中加上 type="module"

新建 app.vue 模板

examples 文件夹下新建 app.vue

<template>
  <div>启动测试div>
template>

新建 main.ts

import {createApp} from 'vue'
import App from './app.vue' // 找不到模块“./app.vue”或其相应的类型声明

const app = createApp(App)

app.mount('#app')

⚠️ 因为直接引入 .vue 文件 TS 会找不到对应的类型声明,所以需要新建 typings(命名没有明确规定,TS 会自动寻找 .d.ts 文件)文件夹来专门放这些声明文件

解决办法:

「根目录」 下新建 typings/vue-shim.d.ts 文件

首先新建 typings 文件夹,然后再新建 vue-shim.d.ts 文件

TypeScript 默认只认 ES 模块,如果要导入 .vue 文件就要 declare module 把他们声明出来,在 vue-shim.d.ts 文件中写入如下内容:

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

完成之后 import App from './app.vue' // 找不到模块“./app.vue”或其相应的类型声明 就不会报错了

配置脚本启动项目

最后在 「根目录」 下的 package.json 文件中配置 scripts 脚本

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

然后在终端输入熟悉的命令:

pnpm run dev

运行结果如下:

VITE v4.0.4  ready in 432 ms

➜  Local:  http://localhost:5173/
➜  Network: use --host to expose
➜  press h to show help

完成后在浏览器中打开链接 http://localhost:xxx/ 就会看到启动测试页面

本地调试

新建包文件

‼️ 下面新建的文件都在 packages 文件夹下面

utils 包

一般 packages 要有 utils 包来存放我们公共方法,工具函数等

既然它是一个包,所以我们新建 utils 目录后就需要初始化它:

  • 终端进入 utils 文件夹执行 pnpm init 然后会生成一个 package.json 文件;
  • 这里需要改一下包名,这里将 name 改成 @karl_fang/utils 表示这个 utils 包是属于 karl_fang 这个组织下的,所以记住发布之前要登录 npm 新建一个组织,例如 karl_fang
{
  "name": "@karl_fang/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
}
karl-ui 组件库包

components 文件夹是用来存放各种 UI 组件的包

新建 components 文件夹并执行 pnpm init 生成 package.json

{
  "name": "karl-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 '@karl_fang/utils'

const result = testfun (1,1)

console.log(result)

运行 tsc index.ts 进行测试

esno

由于组件库是基于 t s的,所以需要安装 esno 来执行 ts 文件便于测试组件之间的引入情况

控制台输入 esno xxx.ts 即可执行 ts 文件

npm i esno -g

包之间本地调试

进入 components 文件夹执行

pnpm install @karl_fang/utils

会发现 pnpm 会自动创建个软链接直接指向我们的 utils 包;此时 components 下的 packages.json 为:

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

会发现它的依赖 @karl_fang/utils 对应的版本为:workspace: ^1.0.0;因为 pnpm 是由 workspace 管理的,所以有一个前缀 workspace 可以指向 utils 下的工作空间从而方便本地调试各个包直接的关联引用

试着开发一个 button 组件

  • components 文件夹下新建 src index.ts 文件,同时在 src 下新建 button 组件目录和 icon 组件目录
  • 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
}

vue3 项目使用 button 组件

  • 直接在 examples 执行 pnpm i karl-ui,此时就会发现 packages.json 中的依赖多了个 "kitty-ui": "workspace:^1.0.0"
  • 这时候就能直接在测试项目 examples 下引入本地的 components 组件库了,在 examples/app.vue 直接引入 Button
<template>
  <div>
    <Button />
  div>
template>

<script lang="ts" setup>
import { Button } from 'karl-ui'
script>

然后运行 npm run dev 即可

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: ['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()
    ]
  }
)

其实到这里就已经可以直接打包了,components 下执行 pnpm run build 就会发现打包了 eslib 两个目录

⚠️ 记得在 components/package.json 中加入如下指令:

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

到这里其实打包的组件库只能给 js 项目使用,在 ts 项目下运行会出现一些错误,而且使用的时候还会失去代码提示功能,这样的话就失去了用 ts 开发组件库的意义了,所以需要在打包的库里加入声明文件(.d.ts),只需要引入vite-plugin-dts,然后修改一下的 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({
        tsConfigFilePath: '../../tsconfig.json'
      }),
      dts({
        // 指定使用的 tsconfig.json,如果不配置也可以在 components 下新建 tsconfig.json
        tsConfigFilePath: '../../tsconfig.json',
        // 因为这个插件默认打包到es下,我们想让lib目录下也生成声明文件需要再配置一个
        outputDir: 'lib',
      }),
    ]
  }
)

然后执行打包命令 npm run build 就会发现 eslib 下就有了 *.t.ts 声明文件

其实后面就可以进行发布了,发布之前更改一下 components 下的 package.json 如下:

{
  "name": "karl-ui",
  "version": "1.0.0",
  "description": "",
  "main": "lib/index.js",
  "module": "es/index.js",
  "files": [
    "es",
    "lib"
  ],
  "scripts": {
    "build": "vite build"
  },
  "keywords": [
    "karl-ui",
    "vue3组件库"
  ],
  "author": "karl fang",
  "license": "MIT",
  "typings": "lib/index.d.ts"
}

  • pkg.module:组件库默认入口文件是传统的 CommonJS 模块,但是如果环境支持 ESModule 的话构建工具会优先使用 module 入口

  • pkg.files:files 是指需要发布到 npm 上的目录,因为不可能 components 下的所有目录都被发布上去

样式问题

引入打包后的组件会发现没有样式,所以需要在全局引入 style.css 才行,那么需要的组件库是每个 css 样式放在每个组件其对应目录下,这样就不需要每次都全量导入 css 样式,下面就来看下如何把样式拆分打包

处理less文件

首先需要做的是将 less 打包成 css 然后放到打包后对应的文件目录下,在 components 下新建 build 文件夹来存放一些打包工具,然后新建 buildLess.ts,首先需要先安装一些工具 cpy 和 fast-glob

pnpm i cpy fast-glob -D -w

cpy

cpy 可以直接复制规定的文件并将文件复制到指定目录,比如 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')

const buildLess = async () => {
  await cpy(`${sourceDir}/**/*.less`, targetLib)
  await cpy(`${sourceDir}/**/*.less`, targetEs)
}

buildLess()

然后在 components/package.json 中新增命令

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

终端执行 pnpm run build:less 就会发现 libes 文件对应目录下就出现了 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 文件,这个命令是单独打包处理 less 文件的,所以在 pnpm run build 后还要运行 pnpm run build:less 才行,那么可以更改 components/package.json 为如下:

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

这样 pnpm run build 后就可以完成 less 文件的处理了

引入 css 文件

现在已经将 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')
        })
      }
    }
  }
]

⚠️ 我们要在 /components/src/button/index.ts 中引入 less 文件,即 import './style/button.less'

引入单元测试框架Vitest

Vitest 旨在将自己定位为 Vite 项目的首选测试框架,在 Vite 项目中使用 Vitest 可以共享相同的插件 vite.config.js,因为组件库是基于 Vite 开发的,所以选择了 Vitest 作为组件库的单元测试框架。

安装与配置

安装

因为测试的是运行于 dom 上的组件库,所以不仅要安装 vitest 还有安装 happy-dom 以及 c8

pnpm add vitest happy-dom c8 -D -w
  • happy-dom:模拟 Web 浏览器,以便用于测试的工具
  • c8:用来展示测试覆盖率

配置

vite.config.tstest 属性下进行 vitest 的相关配置,配置之前需要在文件顶部配置三斜线命令告诉编译器在编译过程中要引入的额外的文件:

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

export default defineConfig(
  {
    build: {......},
    plugins: [......],
    test: {
      environment: "happy-dom"
    },
  }
)

然后在 components/package.json 中添加两条命令

{
	......
  "scripts": {
    ......
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}

举个栗子

执行 pnpm run test 的时候,vitest 会寻找 **/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx} 形式的文件,所以在 components/button/src 文件夹下新建 button.test.ts,写个简单的 2+2=4 的测试代码,其中:

  • describe 描述, describe 会形成一个作用域
  • it 断言
  • expect 期望
import { describe, expect, it } from "vitest";

describe("two plus two is four", () => {
  it("should be 4", () => {
    expect(2 + 2).toBe(4)
  })
})

components 下运行 pnpm run test 的时候会出现如下信息,并且开启了热更新:

✓ src/button/button.test.ts (1)

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  20:52:32
   Duration  518ms (transform 162ms, setup 0ms, collect 17ms, tests 1ms)


 PASS  Waiting for file changes...
       press h to show help, press q to quit

测试组件

components/src/button/button.vue 的内容如下:

<template>
  <button :class="`k-button--${type}`">
    <slot>Hello worldslot>
  button>
template>

<script lang="ts">
export default {
  props: {
    type: {
      type: String,
      default: 'default'
    }
  }
}
script>

测试 slot

因为项目主要是组件库,所以组件是主要测试的东西,首先要安装 Vue 推荐的测试库 @vue/test-utils

pnpm add @vue/test-utils -D -w

这个工具主要提供了一个 mount 方法,通过 mount 实例化一个组件,传入不同参数来测试组件是否符合预期,比如 Button组件写一段测试插槽的代码,一般组件测试文件会放在 __tests__ 文件夹下,所以物品们在 src/button/__tests__ 新建button.test.ts

import { describe, expect, it } from "vitest"; // test 方法的别名是 it

import { mount } from '@vue/test-utils'
import button from '../button.vue'
// The component to test
describe('test Button', () => {
  it("should render slot", () => {
    const wrapper = mount(button, {
      slots: {
        default: 'Hello world'
      }
    })

    // Assert the rendered text of the component
    expect(wrapper.text()).toContain('Hello world')
  })
})

这段测试代码的含义是:当我们默认插槽为"Hello world"时,期望这个组件的text包含"Hello world"

然后执行 pnpm run test 会发现 Button 组件的默认 slot 测试通过了

测试 type

如果要测试 Button 组件传入不同 type 展示不同样式,可以加一段个测试 type 的代码

import { describe, expect, it } from "vitest";

import { mount } from '@vue/test-utils'
import button from '../button.vue'
// The component to test
describe('test Button', () => {
  ......

  it("should have class", () => {
    const wrapper = mount(button, {
      props: {
        type: 'primary'
      }
    })
    expect(wrapper.classes()).toContain('k-button--primary')
  })
})

这段测试代码的含义是:当传入的组件的 typeprimary,期望渲染出的组件包含 k-button--primary 类名

然后执行 pnpm run test 会发现 Button 组件的默认 slot 测试通过了

执行结果如下:

✓ src/button/__test__/button.test.ts (2)

 Test Files  1 passed (1)
      Tests  2 passed (2)
   Start at  21:33:28
   Duration  69ms


 PASS  Waiting for file changes...
       press h to show help, press q to quit

其中关于组件的测试方式还有许多,这里就不再一一举例了,感兴趣的可以到官网 Vitest API 查看

查看测试覆盖率

最后可以执行 pnpm run coverage 来查看测试的覆盖情况:

% Coverage report from c8
------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 button.vue |     100 |      100 |     100 |     100 |                   
------------|---------|----------|---------|---------|-------------------

快速搭建教程

作者为了方便大家快速搭建属于自己的组件库,已经把模板加入了自己的脚手架里,大家可以下载脚手架,然后拉取模板后即可开始组件创作,帮助大家节约大部分的时间,让你们更专注于开发自己的组件库。

下载脚手架

运行命令全局安装作者开发的脚手架 karl-cli

npm i karl-cli -g

更新版本:

npm update karl-cli -g

如果有报错的话,可能是权限不够,在命令行前加 sudo 即可。

安装 pnpm

运行命令全局安 pnpm

npm i pnpm -g

如果有报错的话,可能是权限不够,在命令行前加 sudo 即可。

安装模板

在自己想要安装的目录下运行命令

karl create vue-component

然后控制方向键选择想要安装的模板,我们选择 component-template ,然后等待安装即可。

如果不想下载脚手架也可以直接克隆我的 GitHub 项目:

git clone -b component https://github.com/ox4f5da2/karl-cli-template.git 

克隆后的步骤还是一样的

操作时截图如下:

使用 Vite+TypeScript 打造一个 Vue3 组件库_第1张图片

安装完成时截图如下:

使用 Vite+TypeScript 打造一个 Vue3 组件库_第2张图片

如果想知道如何实现自己的脚手架可以浏览:【开发一个类似 vue-cli 的脚手架工具】

安装依赖

运行以下命令

pnpm i

开始开发组件库

packages/components/src 中创建组件即可,然后在 src 下的 index.ts 中导出,如下所示:

import { default as sbButton } from './sbButton';
......

const components = [
  sbButton,
  ......
];
export default {
  install: (app: any) => {
    for (const comkey in components) {
      app.component(components[comkey].__name, components[comkey]);
    }
  }
};

export {
  sbButton,
  ......
};

查看效果

/examples/app.vue 中直接使用即可,不需要导入组件,如:

<template>
  <div>
    <sb-button>click<sb-button />
  div>
template>
<script lang="ts" setup>
  // js 代码
script>
<style scoped>
/* css 样式 */
<style>

然后运行命令:

pnpm run exm:dev

写在最后

如果大家喜欢可以点赞➕收藏 ,最后参考的是掘金上【东方小月】的组件搭建博客。

你可能感兴趣的:(组件库搭建,typescript,npm,vue.js)