当前位置: 首页 > news >正文

vue3前端组件库的搭建与发布(一)

前言:

最近在做公司项目中,有这么一件事情,很是头疼,就是同一套代码,不同项目,要改相同bug,改好多遍,改的都想吐,于是就想做一个组件库,这样更新一下就全都可以了,当然也是第一次主导组件库的搭建,有哪些不对的,还请各位大佬指出来哈。

准备:

1、node(18+)

2、Verdaccio :是一个Node.js创建的轻量的私有npm proxy registry,可以直接在你本地起一个私有库

npm i verdaccio -g启动:verdaccio

就会出现下面的页面

可以直接创建一个用户:

npm adduser --registry http://localhost:4873/

会让你输入用户名和密码,这个要记好哈,后面上传的时候要用到

开始

看到网上大佬们用的是Monorepo方式,那咱们也用这种方式(虽然不太懂为啥要这样,总之随主流指定出错少,哈哈)

  1. 创建文件夹:

    mkdir?Monorepo?
    # 初始化文件
    pnpm init
    
  2. 在此目录下面创建.npmrc

    # 和npm一样,将别的包的依赖都放在node_modules下,不加的话会放在.pnpm下
    shamefully-hoist = true
    
  3. 新建pnpm-workspace.yaml文件

    packages:
    # 将所有的项目都放到这里
    - ‘packages/*’
    # 示例
    - ‘examples’

4.创建文件目录 packages、examples

packages – 将所有组件放到这里

examples – 测试组件

packages文件目录,里面的所有文件夹都要进行初始化 pnpm init

5、进入到components里面,一定要安装相应的依赖呀

?npm i vue typescript sass element-plus?decimal.js?@element-plus/icons-vue ?-D -w

-D 就不用介绍了

-w 是安装在根目录下

6、配置tsconfig.json文件

{"compilerOptions": {"allowJs": true, //允许编译器编译JS,JSX文件"target": "ES2015", //指定ECMAScript目标版本"useDefineForClassFields": true,"module": "ESNext", //设置程序的模块系统"moduleResolution": "Node", //模块解析策略。默认使用node的模块解析策略"strict": true, //启用所有严格类型检查选项"jsx": "preserve", //preserve模式,在preserve模式下生成代码中会保留JSX以供后续的转换操作使用"sourceMap": true, //生成目标文件的sourceMap文件"resolveJsonModule": true, //允许导入扩展名为“.json”的模块"esModuleInterop": false, //允许module.exports=xxx 导出,由import from 导入.因为很多老的js库使用了commonjs的导出方式,并且没有导出default属性"lib": [ //TS需要引用的库"ESNext","DOM"],"forceConsistentCasingInFileNames": true, //禁止对同一个文件的不一致的引用"allowSyntheticDefaultImports": true, //允许从没有设置默认导出的模块中默认导入"skipLibCheck": true, //忽略所有的声明文件( *.d.ts)的类型检查"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录"paths": { //模块名到基于 baseUrl的路径映射的列表"/@/*": ["src/*"],},"types": [ //要包含的类型声明文件名列表"vite/client","element-plus/global",]},"include": [ //包含的文件"src/**/*.ts","src/**/*.d.ts","src/**/*.tsx","src/**/*.js","src/**/*.jsx","src/**/*.vue",]
}

7、初始化 examples 文件夹

1、初始化
pnpm init2、安装 vite 和 @vitejs/plugin-vue
pnpm vite @vitejs/plugin-vue -D -w3.新建vite.config.ts 并配置 import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({plugins:[vue()]
})4、新建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>注意: vite 是基于 esmodule 的 所以 type="module"
@vitejs/plugin-vue 会默认加载 examples 下的 index.html5、新建app.vue<template><div>app</div>
</template><script setup lang="ts">
</script><style scoped>
</style>6、新建main.tsimport {createApp} from 'vue'
import App from './app.vue'
const app = createApp(App)
app.mount('#app')7、因为直接引入.vue 文件 TS 会找不到对应的类型声明;所以需要新建 typings(命名没有明确规定,TS 会自动寻找.d.ts 文件)文件夹来专门放这些声明文件。declare module '*.vue' {import type { DefineComponent } from "vue";const component:DefineComponent<{},{},any>
}8、在package.json 文件中配置 scripts 脚本"scripts": {"dev": "vite"},
9.pnpm run dev 启动项目

8、初始化packages/components 文件夹

components 文件夹1.目录结构
-- components-- src-- index.ts-- input-number-- inputNumber.vue-- index.ts
-- index.ts
-- package.json2.inputNumber.vue 如下代码3.input-number/index.tsimport InputNumber from './inputNumber.vue'
InputNumber.install = (app) => {app.component(InputNumber.name, InputNumber)
}
export default InputNumber4.components/index.ts
import InputNumber from "./src/input-number/inputNumber.vue";
// 将所有的组件都放到这里进行导出
const components = [InputNumber
]
// 定义install方法const install = (app) => {// 之策所有组件components.forEach(item => {app.component(item.name, item)})
}const DHSUI = {install
}// 支持按需引入
export {InputNumber
}// 导出install方法
export default DHSUI

以input框为例:

src/input-number/inputNumber.vue

<template><el-input v-model="inputValue" class="customInput" v-bind="$attrs" :maxlength="props.maxlength" @input="handleInput"><template #suffix><span class="iconBtn add" @click="add"><el-icon><ArrowUp /></el-icon></span><span class="iconBtn decrease" @click="decrease"><el-icon><ArrowDown /></el-icon></span></template><template v-if="props.isAppend" #append>{{ props.appendText }}</template></el-input>
</template>
<script lang="ts">export default {name: 'InputNumber'
}
</script>
<script setup lang="ts">import { ElInput, ElIcon } from 'element-plus'import 'element-plus/dist/index.css'import {ArrowUp, ArrowDown } from '@element-plus/icons-vue'import { Decimal } from "decimal.js";import { onlyNumOnePoint, canBeMinus } from "@dhs-ui/utils";
import { ref, watch } from 'vue';// 根据最长字符,生成最大值
const generateMaxString = (maxLength: any) => {const maxValue = "9".repeat(maxLength as unknown as number);return maxValue;
};
interface Props {modelValue: string;isAppend?: boolean;appendText?: string;min?: number;max?: number;step?: number;maxlength?: number | string;precision?: number;
}
const props = withDefaults(defineProps<Props>(), {modelValue: "",precision: 4,isAppend: false
});
const emits = defineEmits(["input", "update:modelValue"]);
const inputValue = ref(props.modelValue);
const add = () => {const step = props.step || 1;let val = inputValue.value;if (!val) {val = "0";}let decimalVal = new Decimal(val);if (maxNum() && new Decimal(maxNum()) <= decimalVal) {inputValue.value = decimalVal.toFixed();} else {inputValue.value = decimalVal.plus(step).toFixed();}
};
const decrease = () => {const step = props.step || 1;let val = inputValue.value;if (!val && parseFloat(val) !== 0) val = "0";if (props.min || props.min === 0) {if (parseFloat(val) <= props.min) {val = props.min.toFixed();inputValue.value = val;return;}}let decimalVal = new Decimal(val);inputValue.value = decimalVal.sub(step).toFixed();
};
// number 小数点位数
const vilidateNumberInput = (value: any, number: number) => {let result: any;if (props.min || props.min === 0) {result = onlyNumOnePoint(value, number, !!number);} else {result = canBeMinus(value, number);}return result;
};const maxNum = () => {if (props.max) {return props.max.toFixed();} else {return props.maxlength ? generateMaxString(props.maxlength) : null;}
};
watch(() => props.modelValue,(	newValue: any) => {inputValue.value = newValue;},{ deep: true }
);
watch(inputValue, (nv: any) => {emits("update:modelValue", nv);
});
const handleInput = (val: any) => {inputValue.value = vilidateNumberInput(val, props.precision);emits("input", val);
};
</script><style scoped lang="scss">
.customInput {.iconBtn {position: absolute;right: 1px;display: block;width: 32px;background-color: #f5f7fa;border-left: 1px solid var(--default-border-color);height: 15px;line-height: 15px;cursor: pointer;}.add {top: 1px;border-radius: 0 4px 0 0;}.decrease {border-top: 1px solid var(--default-border-color);bottom: 1px;border-radius: 0 0 4px 0;}&.is-disabled {.add,.decrease {pointer-events: none;}}
}
</style>

9、在examples/app.vue测试组件

<template><div><InputNumber :modelValue="inputValue" /></div>
</template><script setup lang="ts">
import { ref } from 'vue';
import {InputNumber} from '../packages/components/src/input-number/inputNumber.vue';const inputValue = ref(0)
</script><style scoped></style>

出现了你所要的组件就说明可以进行打包了。

10、在components文件夹中打包组件

components 文件夹 新建vite.config.ts
这里我们选择打包cjs(CommonJS)和esm(ESModule)两种形式,cjs模式主要用于服务端引用(ssr),而esm就是我们现在经常使用的方式,它本身自带treeShaking而不需要额外配置按需引入(前提是你将模块分别导出),非常好用~

为了也能在ts项目中使用,还需要自动生成类型声明文件

pnpm add vite-plugin-dts@1.4.1 -D -wimport { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";
export default defineConfig({build: {//打包文件目录outDir: "es",//压缩//minify: false,rollupOptions: {//忽略打包的文件external: ["vue", "element-plus"],input: ["index.ts"],output: [{//打包格式format: "es",//打包后文件名entryFileNames: "[name].mjs",//让打包目录和我们目录对应preserveModules: false,exports: "named",//配置打包根目录dir: "../DHS-UI/es",},{//打包格式format: "cjs",//打包后文件名entryFileNames: "[name].js",//让打包目录和我们目录对应preserveModules: false,exports: "named",//配置打包根目录dir: "../DHS-UI/lib",},],},lib: {entry: "./index.ts",},},plugins: [vue(),dts({entryRoot: "./src",outputDir: ["../DHS-UI/es/src", "../DHS-UI/lib/src"],//指定使用的tsconfig.json为我们整个项目根目录下,如果不配置,你也可以在components下新建tsconfig.jsontsConfigFilePath: "../../tsconfig.json",}),],
});

配置同目录下的package.json文件

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

11、运行 build 进行打包,会在目录中生成打包好的包

11、打包好的文件,进行初始化

pnpm init

修改package.json 文件

{"name": "dhs-uii","version": "1.0.2","description": "","main": "lib/index.js","module": "es/index.mjs","files": ["es","lib"],"scripts": {"test": "echo "Error: no test specified" && exit 1"},"sideEffects": ["**/*.css"],"keywords": ["dhs-ui","vue3组件库","frontend","element-plus"],"author": "dengdeng","license": "ISC","typings": "lib/index.d.ts"
}

下一章进行发布,及遇到的问题。

感谢大佬文章:搭建一个组件库(vue3)_vue3组件库搭建-CSDN博客

相关文章:

vue3前端组件库的搭建与发布(一)

前言&#xff1a; 最近在做公司项目中&#xff0c;有这么一件事情&#xff0c;很是头疼&#xff0c;就是同一套代码&#xff0c;不同项目&#xff0c;要改相同bug&#xff0c;改好多遍&#xff0c;改的都想吐&#xff0c;于是就想做一个组件库&#xff0c;这样更新一下就全都可…...

COMSOL快捷键及内置函数

文章目录 COMSOL快捷键使用COMSOL算子求最大值和最小值COMSOL内置函数3.1 解析函数3.2 插值函数3.3 分段函数3.4 高斯脉冲函数3.5 斜坡函数3.6 矩形函数3.7 波形函数3.8 随机函数3.9 Matlab函数3.10 SWITCH函数 COMSOL快捷键 Ctrl&#xff0b;/ 可快速打开预定义的物理量列表。…...

HUAWEI-eNSP交换机链路聚合(手动负载分担模式)

配置思路:HUAWEI交换机链路聚合有LACP模式跟手动负载分担模式,本文主打手动负载分担模式:首先交换机-PC之间划分基本vlan,交换机-交换机之间创建链路聚合组,划分端口至链路聚合分组(缺省模式为手动负载分担模式)。结果验证要求同vlan可以ping通,关闭某个聚合端口后仍可…...

番外篇 | Hyper-YOLO:超图计算与YOLO架构相结合成为目标检测新的SOTA !

前言:Hello大家好,我是小哥谈。Hyper-YOLO,该方法融合了超图计算以捕捉视觉特征之间复杂的高阶关联。传统的YOLO模型虽然功能强大,但其颈部设计存在局限性,限制了跨层特征的融合以及高阶特征关系的利用。Hyper-YOLO在骨干和颈部的联合增强下,成为一个突破性的架构。在COC…...

【MATLAB第109期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数

【MATLAB第108期】基于MATLAB的带置信区间的RSA区域敏感性分析方法&#xff0c;无目标函数 参考第64期文章【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用&#xff08;含无目标函数&#xff0c;考虑代理模型&#xff09; 创新点&#xff1a; 1、采…...

Bootstrap 表格

Bootstrap 表格 引言 Bootstrap 是一个流行的前端框架&#xff0c;它提供了一套丰富的工具和组件&#xff0c;用于快速开发响应式和移动设备优先的网页。在本文中&#xff0c;我们将重点讨论 Bootstrap 中的表格组件&#xff0c;包括其基本结构、样式以及如何使用 Bootstrap …...

【论文阅读】Computing the Testing Error without a Testing Set

https://blog.csdn.net/qq_40021158/article/details/109485216 可以使用测试集来估计训练集和测试集之间的性能差距&#xff0c;但是要避免过度拟合测试数据几乎是不可能的。 使用隔离的测试集可能会解决此问题&#xff0c;但这需要不断更新数据集&#xff0c;这是一项非常昂贵…...

Visio——同一个工程导出的PDF文件大小不一样的原因分析

现象 在不同电脑&#xff0c;导出来的PDF文件大小不一样。 原因分析 文件小的未将字体嵌入&#xff0c;文件大的已经将字体嵌入了。...

【ETCD】ETCD 架构揭秘:内部各组件概览

ETCD 的主要组件及它们之间的关联关系如下&#xff1a; 目录 1. Client&#xff08;客户端&#xff09;2. gRPC 接口3. Etcd Server Main Loop&#xff08;ETCD 主循环&#xff09;4. Raft&#xff08;共识模块&#xff09;5. Peer Etcd Nodes&#xff08;ETCD 集群节点&#x…...

Qt WORD/PDF(四)使用 QAxObject 对 Word 替换(QWidget)

关于QT Widget 其它文章请点击这里: QT Widget 国际站点 GitHub: https://github.com/chenchuhan 国内站点 Gitee : https://gitee.com/chuck_chee 姊妹篇: Qt WORD/PDF&#xff08;一&#xff09;使用 QtPdfium库实现 PDF 操作 Qt WORD/PDF&#xff08;二…...

音视频学习(二十四):hls协议

基本原理 HLS协议通过将视频文件切分成多个小的媒体段&#xff08;通常是10秒左右的.ts文件&#xff09;&#xff0c;并通过HTTP传输给客户端。视频播放过程中&#xff0c;客户端按顺序请求这些小段文件来逐步播放整个视频流。HLS还支持多种码率&#xff0c;以便适应不同网络条…...

UniDepth 学习笔记

摘要 准确的单目度量深度估计&#xff08;MMDE&#xff09;是解决三维感知和建模中下游任务的关键。然而&#xff0c;最近的MMDE方法的显著准确性仅限于其训练领域。这些方法存在适度的域间隙&#xff0c;也不能推广到看不见的域&#xff0c;这阻碍了它们的实际适用性。本文提出…...

PVE——OpenWRT 硬盘 size单位的调整

​​​​​ 问题&#xff1a;初始状态为120MB 还需要进行计算&#xff0c;如果通过图形界面添加磁盘会出现单位不变的情况。 进入命令行前记得给你的虚拟机拍照&#xff0c;防止误操作 通过ssh 进入PVE命令行 按需添加容量即可 不到1G 会显示M 超过1G 不是G整数均为M单位。 …...

Android-ImagesPickers 拍照崩溃优化

Android-ImagesPickers 作为老牌图片选择器&#xff0c;帮助了很多牛马宝宝&#xff0c;刚好最近用到了多相册选择以及拍照&#xff0c;可能是高版本机型问题&#xff0c;导致拍照后就闪退 原作者文章以及git Android实用视图动画及工具系列之九&#xff1a;漂亮的图片选择器…...

Linux dd 命令详解:工作原理与实用指南(C/C++代码实现)

这段代码是一个模仿 Linux dd 命令的工具&#xff0c;它用于在不同文件之间复制数据。dd 是一个非常强大的命令行工具&#xff0c;可以用于数据备份、转换和复制。下面我将详细解释这段代码的原理、实现方式以及如何运行和测试。 Linux dd 命令的工作原理 dd 命令是 Unix 和 …...

Golang学习历程【第一篇 入门】

Golang学习历程【第一篇 入门Hello World】 1. 学习文档2. Window 本地安装Go2.1 安装2.2 验证 3. 开发环境——VsCode3.1 VsCode 安装3.2 安装插件3.2.1 language 语言汉化插件安装3.2.2 Go插件安装 4. Hello World 入门4.1 建工程4.2 创建项目文件4.3 编写Hello World程序4.4…...

青少年编程与数学 02-004 Go语言Web编程 01课题、Web应用程序

青少年编程与数学 02-004 Go语言Web编程 01课题、Web应用程序 课题摘要:一、Web应用程序二、Web服务器&#xff08;一&#xff09;什么是Web服务器&#xff08;二&#xff09;Web服务器配置1. 选择服务器软件2. 安装服务器软件3. 配置服务器4. 安全设置5. 部署网站内容6. 测试服…...

【mysql】如何解决主从架构从库延迟问题

目录 1. 说明2.优化主库的写入性能3. 优化网络性能4. 增强从库的硬件性能5. 调整从库的配置6. 主从架构优化7. 监控和调优8.使用 GTID 和 Group Replication 1. 说明 1.在 MySQL 数据库中&#xff0c;从库延迟&#xff08;replication lag&#xff09;是指主库和从库之间的数据…...

前端学习-获取DOM对象(二十一)

目录 前言 目标 提问 学习路径 根据CSS选择器来获取DOM元素 其他获取DOM元素的方法 根据CSS选择器来获取DOM元素 选择匹配的第一个元素 语法 示例 参数 返回值 选择匹配的多个元素语法 参数 字符串返回值 示例 补充 其它获取DOM元素方法 根据id获取一个元素 …...

PCL点云库入门——PCL库中Eigen数学工具库的基本使用(持续更新)

0、前言 PCL点云库中的算法都基于Eigen数学工具库来实现的&#xff0c;因此&#xff0c;掌握Eigen库对于深入理解和应用PCL点云库至关重要。Eigen库不仅提供了高效的矩阵和向量运算&#xff0c;还支持复杂的线性代数、几何变换等操作&#xff0c;为PCL点云处理提供了强大的数学…...

CLion Inlay Hints - 取消 CLion 灰色的参数和类型提示

CLion Inlay Hints - 取消 CLion 灰色的参数和类型提示 1. Parameter hints for C/C1.1. Toggle parameter hints globally 2. Type hints for C/C2.1. Toggle type hints&#xfeff; globally 3. Toggle inlay hints globallyReferences https://www.jetbrains.com/help/clio…...

2025山东科技大学考研专业课复习资料一览

[冲刺]2025年山东科技大学020200应用经济学《814经济学之西方经济学[宏观部分]》考研学霸狂刷870题[简答论述计算题]1小时前[强化]2025年山东科技大学085600材料与化工《817物理化学》考研强化检测5套卷22小时前[冲刺]2025年山东科技大学030100法学《704综合一[法理学、国际法学…...

vue3 v-model实例之二,tab标签页的实现

<template><div><Tab v-model"activeTab" :list"tabs" /><div><p>当前激活的 Tab 索引: {{ activeTab }}</p></div></div> </template><script setup> import { ref } from vue; import Tab …...

东方通TongWeb7.0.4.9M4部署SuperMap iServer 11.2.1

一、软件版本 操作系统: CentOS Linux release 7.5.1804 (Core)JDK:11.0.18东方通&#xff1a;TongWeb7.0.4.9M4SuperMap iServer&#xff1a;11.2.1 JDK和TongWeb软件分享&#xff1a; 链接: https://pan.baidu.com/s/1HGDTPnPID0PEOMbg3FjTVQ?pwdbh8v 提取码: bh8v 东方通软…...

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框&#xff08;不需要设置QPen&#xff0c;因为默认是不绘制边框的&#xff09;QPen pen(Qt::NoPen);// QPen pen…...

2012年西部数学奥林匹克试题(几何)

2012/G1 △ A B C \triangle ABC △ABC 内有一点 P P P, P P P 在 A B AB AB, A C AC AC 上的投影分别为 E E E, F F F, 射线 B P BP BP, C P CP CP 分别交 △ A B C \triangle ABC △ABC 的外接圆于点 M M M, N N N. r r r 为 △ A B C \triangle ABC △ABC 的内…...

8位移位寄存器的verilog语言

module shift_register (output reg [7:0] Q, // 8位移位寄存器输出input D, // 输入数据input rst, // 复位信号input clk // 时钟信号 );always (posedge clk) beginif (!rst)Q < 8b00000000; // 复位时将Q清零elseQ < {Q[6:0], D}; // 否则…...

【苍穹外卖】学习心得体会-随笔

前言 写了很久&#xff0c;终于可以完整运行项目了&#xff0c;记录下这几天的心得体会回顾一下知识点 第一天、Git 分布式版本控制工具 一、Git概述 定义&#xff1a;是分布式版本控制工具&#xff0c;用于管理软件开发中的源代码文件&#xff0c;像Java类、xml文件、html…...

MySQL学习之表的增删改

MySQL学习之表的增删改 语法总结&#xff1a; INSERT INTO 表名 (字段名1, 字段名2, ...) VALUES (值1, 值2, ...); //指定字段添加数据 INSERT INTO 表名 VALUES (值1, 值2, ...); //给全部字段添加数据 INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...), (值1, …...

电脑excel词典(xllex.dll)文件丢失是或损坏是什么原因?“xllex.dll文件缺失“要怎么解决?

Excel词典&#xff08;xllex.dll&#xff09;文件丢失或损坏&#xff1f;别担心&#xff0c;这里有解决之道&#xff01; 在日常的电脑使用和办公软件操作中&#xff0c;我们偶尔会碰到一些让人头疼的问题&#xff0c;比如Excel突然提示“Excel词典&#xff08;xllex.dll&…...