我正在参加会员专属活动-源码共读第一期,点击参加

在很早的时候就开发了色彩挑选vcolorpicker了,github 上的 star 也有 近300了,因功用比较稳定然后一向疏于更新到现在也N年了。刚好想参加下的活动,以及支撑下vue3及vite就有了此文。

以下就根据vcolorpicker为案例,叙述运用 vue3+vite 从开发到发布npm的全流程。

vColorPicker 文档 DEMO

一、技能栈

直接运用 vite 创立初始 vue 项目,详细就不提了直接看官方文档就成

  • vite
  • vue3
  • TS
  • @vueuse/core 一些工具办法,十分实用
  • git-cz 用于代码提交标准
  • release-it 用于主动提高版别、打tag、生成改动日志等

二、思路纲要

要想建立一个组件库,先要有一个大概的思路,后续的开发方向就十分明确了。

  1. 增加代码提交标准
  2. 增加主动提高版别、打tag、生成改动日志等
  3. 规划项目目录结构
  4. 编写组件
  5. 编写示例
  6. 打包装备
  7. 编写模块包声明文件
  8. 发布到npm

三、增加代码提交标准

1. 装置 git-cz 工具包

pnpm i -D git-cz

2. 增加提交脚本指令

package.json文件中增加以下内容

{
  "scripts": {
    "commit": "git-cz"
  }
}

3. 运用 pnpm commit提交代码

代码更改后运用指令提交代码

pnpm commit

运用提交指令后,会提示挑选以何种方式提交代码

@zuley ➜ /workspaces/vue-color-picker (2.0 ✗) $ pnpm commit
> vcolorpicker@2.0.0 commit /workspaces/vue-color-picker
> git-cz
? Select the type of change that you're committing: (Use arrow keys or type to search)
❯   test:       Adding missing tests # 增加测试
    feat:       A new feature # 新特性
    fix:        A bug fix # 修复bug
    chore:      Build process or auxiliary tool changes # 构建过程或辅助工具更改
  ✏️  docs:       Documentation only changes # 仅文档修正
    refactor:   A code change that neither fixes a bug or adds a feature # 即不修复过错也不增加功用的修正
    style:      Markup, white-space, formatting, missing semi-colons... #符号、空格、格局化、缺少分号等...
(Move up and down to reveal more choices) # 上下移动回车挑选

回车后下一步输入提交的简短描绘

? Write a short, imperative mood description of the change:
  [-------------------------------------------------------------] 55 chars left
   docs: 修正文档

输入内容后回车,下一步输入提交较详细的描绘

? Provide a longer description of the change:
  修正 README.md 文件中的内容

输入内容后回车,下一步输入列出较大的改动,没有就直接跳过

? List any breaking changes
  BREAKING CHANGE: 

回车后,下一步可挑选输入要当时提交需求关联的 issues的ID格局如:#4,一般用于修复用户提交的问题

? Issues this commit closes, e.g #123: #4

四、增加主动提高版别、打tag、生成 changelog 等

1. 运用release-it工具初始化

npm init release-it

履行初始化后,提示是否装置依赖,直接挑选是。

接着提示是否每次推送代码的时候,都发布到 release

? Publish a GitHub Release with every release? › (Y/n)

然后提示挑选将装备增加到独立文件仍是 package.json

? Where to add the release-it config? ›
❯   .release-it.json
    package.json

再装置 changelog 插件

pnpm i @release-it/conventional-changelog -D

紧接着修正 package.jsonrelease-it装备

{
  "release-it": {
    "github": {
      "release": false
    },
    "git": {
      "commitMessage": "release: v${version}"
    },
    "npm": {
      "publish": false
    },
    "hooks": {
      "after:bump": "echo 更新版别成功"
    },
    "plugins": {
      "@release-it/conventional-changelog": {
        "preset": "angular",
        "infile": "CHANGELOG.md"
      }
    }
  }
}

2. 运用 pnpm release构建改动并推送代码

初始化及装备完成后,运用指令构建改动

pnpm release

履行后得到以下输出

@zuley ➜ /workspaces/vue-color-picker (2.0) $ pnpm release
> vcolorpicker@2.0.0 release /workspaces/vue-color-picker
> release-it
 Let's release vcolorpicker (2.0.0...2.0.1)
Changelog:
## [2.0.1](https://github.com/zuley/vue-color-picker/compare/v1.1.0...v2.0.1) (2022-11-26)
✔ echo 更新版别成功
Changeset:
A  CHANGELOG.md
 M package.json
? Commit (release: v2.0.1)? Yes
? Tag (v2.0.1)? Yes
? Push? Yes
 Done (in 249s.)
  1. 主动提高版别号
  2. 主动输出改动日志
  3. 主动提交了输出的改动代码
  4. 主动打好了 tag
  5. 主动将提交推送到了 github

留意:此指令用于发布版别都提交,会主动晋级版别号改动日志等。正常代码提交运用惯例的推送指令。

五、规划目录结构

1. 目录结构

.
...
|-- examples      // 原 src 目录,改成 examples 用作示例展现
|-- packages      // 新增 packages 用于编写寄存组件
...
. 

2. 原 src 目录,改成 examples 用作示例展现

重命名 src目录为examples后项目要能正常运转需修正对应位置的装备如下

修正 vite.config.ts的装备

// vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      // 修正这一行的  src 为 examples
      // '@': fileURLToPath(new URL('./src', import.meta.url))
      '@': fileURLToPath(new URL('./examples', import.meta.url))
    }
  }
})

修正tsconfig.json的装备

{
  "extends": "@vue/tsconfig/tsconfig.web.json",
  // 修正这一行的 src 为 examples
  // "include": ["env.d.ts", "examples/**/*", "examples/**/*.vue"],
  "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      // 修正这一行的 src 为 examples
      // "@/*": ["./src/*"]
      "@/*": ["./examples/*"]
    }
  },
  "references": [
    {
      "path": "./tsconfig.config.json"
    }
  ]
}

修正index.html 的引进

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- 修正这儿的 src 为 examples -->
    <script type="module" src="/examples/main.ts"></script>
  </body>
</html>

3. 新增 packages 用于编写寄存组件

新增examples同级目录packages并创立一个main.ts

// packages/main.ts
console.log('我被引进了')
export default {
  x: '我是vColorPicker组件'
}

tsconfig.json中增加此目录的支撑

{
  // 增加 "packages/**/*", "packages/**/*.vue"
  "include": ["env.d.ts", "examples/**/*", "examples/**/*.vue", "packages/**/*", "packages/**/*.vue"],
}

examples/main.ts中引进packages/main.ts

import vColorPicker from './../packages/main'
console.log('vColorPicker', vColorPicker)

运转后检查控制台作用

超详细:Vite建立组件库改造300星色彩挑选器vcolorpicker

此刻此目录已成功增加

六、编写组件

以上咱们已装备好对新目录架构的支撑,接下来咱们测验编写组件。以下咱们以一个已发布到 npm 的组件为示例。

Github – 色彩挑选器:vcolorpicker

1. 创立一个新组件

  1. packages 目录下,一切的单个组件都以文件夹的方式存储,一切这儿创立一个目录 color-picker/
  2. color-picker/ 目录下创立 src/ 目录存储组件源码
  3. /color-picker 目录下创立 index.ts 文件对外供给对组件的引证。
.
├── packages
│   ├── color-picker
│   │   ├── index.ts
│   │   └── src
│   │       └── index.vue
│   └── main.ts

修正/packages/color-picker/src/index.vue供给组件详细完成引证

这儿要留意的是组件姓名无法在<script setup> 中声明,需求另起一个。 参阅官方材料:cn.vuejs.org/api/sfc-scr…

<script lang="ts">
// 声明无法在 <script setup> 中声明的选项
export default {
  name: "colorPicker"
}
</script>
<script setup lang="ts">
const props = defineProps<{
  modelValue: string
}>()
const emits = defineEmits<{
  (e: 'update:modelValue', value: string): void
}>()
</script>
<template>
  测试组件
  <div class="add" @click="$emit('update:modelValue', 'ddd')">add</div>
</template>

修正/packages/color-picker/index.ts文件,对外供给引证

import type { Plugin } from "vue"
// 导入组件
import colorPicker from "./src/index.vue"
// 为组件供给 install 装置办法,供按需引进
colorPicker.install = function (app, options) {
  app.component(colorPicker.name, colorPicker)
} as Plugin
// 默许导出组件
export default colorPicker

2. 整合一切组件,对外导出,即一个完好的组件库

修正/packages/main.ts文件,对外供给引证

import type { Plugin } from 'vue'
// 导入色彩挑选器组件
import colorPicker from './color-picker'
// 存储组件列表
const components = [
  colorPicker
]
// 界说 install 办法,接纳 app 作为参数。假如运用 use 注册插件,则一切的组件都将被注册
const install: Plugin['install'] = function (app) {
  // 遍历注册大局组件
  components.map(component => app.component(component.name, component))
}
export default {
  install,
  colorPicker
}

七、编写示例

1、在示例中导入组件库

import { createApp } from 'vue'
import App from './App.vue'
// 导入组件库
import vColorPicker from './../packages/main'
const app = createApp(App)
// 注册组件库
app.use(vColorPicker)
app.mount('#app')

2、在示例中运用组件库的组件

在上一步中运用 app.use() 大局注册后,即可在任意页面直接运用了,而不需别的引进。当然也能够按需引进,这儿暂时不打开。

<script setup lang="ts">
import { ref } from 'vue';
const color = ref('')
const headleChangeColor = (val: string) => {
  console.log('色彩改动', val)
}
</script>
<template>
  <colorPicker v-model="color" @update:modelValue="headleChangeColor" />
</template>

八、打包装备

1、package.json中新增一条编译为库的指令

{
  "scripts": {
    "lib": "vite build --mode lib",
  }
}

2、装备vite.config.ts

import { fileURLToPath, URL } from 'node:url'
import { resolve } from 'path'
import { defineConfig } from 'vite'
import type { UserConfigExport } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig((env) => {
  const defaultConfig: UserConfigExport = {
    plugins: [vue()],
    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./examples', import.meta.url))
      }
    }
  }
  // 当履行 pnpm lib 设置环境变量 --mode lib 时
  if (env.mode === 'lib') {
    defaultConfig.build = {
      lib: {
        entry: resolve(__dirname, 'packages/main.ts'),
        name: 'vcolorpicker',
        fileName: 'vcolorpicker'
      },
      rollupOptions: {
        // 打包疏忽 vue
        external: ['vue'],
        output: {
          globals: {
            vue: 'Vue'
          },
          // 输出目录
          dir: 'lib'
        }
      }
    }
  }
  return defaultConfig
})

装备好后,履行 lib 指令,可针对走lib的装备。这儿主要必须要加判断,否则针对的便是一切的编译指令。

九、编写模块包声明文件

在根目录或许依据个人需求创立进口 .d.ts,这个主要是其他项目装置本模块时候,指定的声明文件解析。这儿只做简略示例,各位依据实践需求就行。

// index.d.ts
import type { App } from 'vue';
declare const _default: {
  install: (app: App<any>) => App<any>;
};
export default _default;

十、发布到npm,方便在项目中引证

到这儿咱们一个完好的组件库现已开发完成了,接下来便是将其发布到 npm 以供后期运用。

1、package.json中新增一条编译为库的指令

{
  "scripts": {
    "lib": "vite build --mode lib",
  }
}

2、装备 package.json 文件中发布到 npm 的字段

参数 说明
name 包名,该姓名是唯一的。可在 npm 官网查找姓名,假如存在则需换个姓名。
version 版别号,每次发布至 npm 需求修正版别号,不能和历史版别号相同。
description 包描绘
type 指定包类型
main 界说这个 package 的进口文件位置。
显现界说 “type”: “module”,那么它指向的便是 ES6 模块,假如没有则解释为CommonJS模块
exports 同上,处理复杂进口,优先级高于main
types 指定TS声明文件进口
keyword 关键字,便于用户查找
author 作者
private 是否私有,需求修正为 false 才能发布到 npm
license 开源协议

参阅装备如下

{
  "name": "vcolorpicker",
  "version": "2.0.11",
  "type": "module",
  "description": "根据 Vue3 的色彩挑选器",
  "main": "./lib/vcolorpicker.js",
  "module": "./lib/vcolorpicker.js",
  "types": "./index.d.ts",
  "exports": {
    ".": {
      "import": "./lib/vcolorpicker.js",
      "require": "./lib/vcolorpicker.mjs"
    },
    "./lib/*": "./lib/*"
  },
  "keywords": [
    "vcolorpicker",
    "colorpicker",
    "color-picker",
    "vue-color-picker"
  ],
  "author": "zuley",
  "license": "MIT",
  "homepage": "https://github.com/zuley/vue-color-picker",
  "private": false,
}

3、增加 .npmignore 文件,设置疏忽发布文件

咱们发布到 npm 中,只有编译后的 lib 目录、package 目录 等才是需求被发布的。所以咱们需求设置疏忽目录和文件。

# 疏忽目录
examples/
public/
dist/
.vscode/
.devcontainer/
# 疏忽指定文件
vite.config.ts
pnpm-lock.yaml
index.html
env.d.ts
CHANGELOG.md
.gitignore
*.map

4、登录到NPM

首先需求到 npm 上注册一个账号,注册过程略。

假如装备了淘宝镜像,先设置回npm镜像:

npm config set registry http://registry.npmjs.org 

然后在终端履行登录指令,输入用户名、暗码、邮箱即可登录。

# 履行登录指令
npm login
# 输入用户名
Username: 用户名
Password: 暗码
Email: (this IS public) 邮箱
npm notice Please check your email for a one-time password (OTP)
Enter one-time password: 邮箱中接纳的一次性暗码

5、发布到NPM

履行发布指令,发布组件到 npm

npm publish

履行过程如下

npm notice
npm notice   vcolorpicker@2.0.1
npm notice === Tarball Contents === 
npm notice 26B    README.md              
npm notice 4.3kB  lib/favicon.ico        
npm notice 1.8kB  lib/style.css          
npm notice 10.1kB lib/vcolorpicker.mjs   
npm notice 7.7kB  lib/vcolorpicker.umd.js
npm notice 1.6kB  package.json           
npm notice 328B   tsconfig.json          
npm notice === Tarball Details === 
npm notice name:          vcolorpicker                            
npm notice version:       2.0.1                                   
npm notice filename:      vcolorpicker-2.0.1.tgz                  
npm notice package size:  8.9 kB                                  
npm notice unpacked size: 25.8 kB                                 
npm notice shasum:        dcb708dc942082e78e0a84c251f528bc7762fc29
npm notice integrity:     sha512-2HbIL9dBAP4eK[...]Y/6J5cHwcu3cQ==
npm notice total files:   7                                       
npm notice 
npm notice Publishing to https://registry.npmjs.org/
+ vcolorpicker@2.0.1

6、发布成功

发布成功后稍等几分钟,即可在 npm 官网查找到。

7、运用新发布到组件库

pnpm i vcolorpicker -S

运用

// 在 main.ts 引进并注册
import { createApp } from 'vue'
import vColorPicker from 'vcolorpicker'
import 'vcolorpicker/lib/style.css'
const app = createApp(App)
app.use(vColorPicker)
// 在组件中运用
<template>
  <colorPicker v-model="color" @change="headleChangeColor"></colorPicker>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const color = ref('#ff0000')
const headleChangeColor = (color: string) => {
  console.log(`色彩值改动事情:${color}`)
}
</script>

十一、项目地址

Github 地址:https://github.com/zuley/vue-color-picker

npm 地址:https://www.npmjs.com/package/vcolorpicker

DEMO 演示:http://vue-color-picker.rxshc.com

十二、参阅

Moule 的加载完成:https://es6.ruanyifeng.com/#docs/module-loader

TypeScript声明文件:https://www.typescriptlang.org/docs/handbook/declaration-files/publishing.html

Vite官方文档:https://cn.vitejs.dev/guide/

详解:Vue cli3 库形式建立组件库并发布到 npm:https:///post/6844903687668629518