vite+tailwind封装组件库

news2025/6/8 6:13:38

前言

演示视频

https://www.bilibili.com/video/BV1EST3zPEyP/?spm_id_from=333.1387.homepage.video_card.click

参考

https://juejin.cn/post/7112295067682865166

https://juejin.cn/post/7046187185615142949

代码仓库

https://gitee.com/malguy/vite-components-lib-tutorial

初始化项目

创建vite

直接使用命令行

pnpm create vite react-components
cd react-components
pnpm i

你也可以用我的脚手架面板(推销一下😁🤓)

malred/cli-panel

无需联网, 因为是用文件复制的方法创建的

安装tailwind

使用tailwind v3

Installation - Tailwind CSS

pnpm install -D tailwindcss@3 postcss autoprefixer
# npx tailwindcss init -p
pnpm dlx tailwindcss@3 init -p

将路径添加到 **<font style="color:rgb(15, 23, 42);">tailwind.config.js</font>** 文件中的所有模板文件中。

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    // 使用react时
    "./src/**/*.{js,ts,jsx,tsx}",
    // 使用vue时
    "./src/**/*.{vue,js,ts,jsx,tsx}",
    // 使用svelte时
    "./src/**/*.{svelte,js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

将Tailwind每个层的 **<font style="color:rgb(15, 23, 42);">@tailwind</font>** 指令添加到您的 **<font style="color:rgb(15, 23, 42);">./src/app.css</font>** 文件中。

@tailwind base;
@tailwind components;
@tailwind utilities;

写一个button组件

src/components/Button/Button.jsx

// src/components/button/index.tsx
/*
 * @Author WangZhiGang
 * @Date 2025-06-07 05:58:37
 * @Description 
 */
import './button.css'

import * as React from "react";

interface Props {
    size: 'lg' | 'md' | 'sm'
    children: string | React.ReactNode
}

const Button = ({
                   size, children
               }: Props) => {
    const className = size + " base "

    return (
        <button
            className={className}
        >
            {children}
        </button>
    );
};

export default Button;

如果觉得tailwind样式太长, 可以写一个css

button {
    &.base {
        @apply text-white bg-blue-500 rounded-md
    }

    &.sm {
        @apply text-xs p-2
    }

    &.md {
        @apply text-sm p-4
    }

    &.lg {
        @apply text-lg p-8
    }
}

在index.js中导出

// !!! 重要 包含@tailwind的css必须导出, 否则新项目会丢失变量 !!!
import './index.css'
import './App.css'

import Button from "./components/button/index.jsx";

export {
    Button as MalButton
}

修改vite配置文件

import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path'
// const path = require("path");

const resolvePath = (str) => path.resolve(__dirname, str);

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react()],
    // 防止 vite 将 rgba() 颜色转化为 #RGBA 十六进制
    cssTarget: 'chrome61',
    resolve: {
        alias: {
            "@": path.resolve(__dirname, "./src"),
        },
    },
    // 打包编译配置
    build: {
        rollupOptions: {
            // 请确保外部化那些你的库中不需要的依赖
            external: ["react", "react-dom"],
            output: {
                // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
                globals: {
                    react: "react",
                    "react-dom": "react-dom",
                },
            },
        },
        lib: {
            // 打包入口文件, 使用时从入口进行寻找依赖
            entry: resolvePath("src/index.js"),
            name: "mal-react-components",
            // 打包后文件名 format表示不同的规范(commonjs之类的) 
            // 如果打包成 UMD 格式,文件名可能是 mal-vue3-components.umd.js。
            // 如果打包成 ES Module 格式,文件名可能是 mal-vue3-components.es.js
            fileName: format => `mal-react-components.${format}.js`,
        },
    }
})
import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
// import tailwindcss from 'tailwindcss';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [vue()],
    // css: {
    //     postcss: {
    //         plugins: [tailwindcss],
    //     }
    // },
    // 打包编译配置
    build: {
        rollupOptions: {
            // 请确保外部化那些你的库中不需要的依赖
            external: ['vue'],
            output: {
                // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
                globals: {
                    vue: 'Vue',
                },
            },
        },
        lib: {
            // 打包入口文件, 使用时从入口进行寻找依赖
            entry: './src/index.js',
            // 名称
            name: 'mal-vue-components',
            // 打包后文件名 format表示不同的规范(commonjs之类的) 
            // 如果打包成 UMD 格式,文件名可能是 mal-vue3-components.umd.js。
            // 如果打包成 ES Module 格式,文件名可能是 mal-vue3-components.es.js
            fileName: (format) => `mal-vue3-components.${format}.js`,
        },
    }
})

如果使用的是ts

pnpm i @rollup/plugin-typescript tslib
# 在vite.config文件里使用node的依赖需要安装
pnpm i @types/node --save-dev
import {defineConfig} from 'vite'
import react from '@vitejs/plugin-react'
import typescript from '@rollup/plugin-typescript'
// 想在ts使用node的依赖, 需要安装 @types/node
import { resolve } from "node:path";

const resolvePath = (str: string) => resolve(__dirname, str);

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react()],
    resolve: {
        alias: {
            "@": resolve(__dirname, "./src"),
        },
    },
    // 打包编译配置
    build: {
        rollupOptions: {
            // 请确保外部化那些你的库中不需要的依赖
            external: ["react", "react-dom"],
            output: {
                // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
                globals: {
                    react: "react",
                    "react-dom": "react-dom",
                },
            },
            plugins: [
                typescript({
                    target: "es2015", // 这里指定编译到的版本,
                    rootDir: resolvePath("src/"),
                    declaration: true,
                    declarationDir: resolvePath("dist"),
                    exclude: resolvePath("node_modules/**"),
                    allowSyntheticDefaultImports: true,
                }),
            ],
        },
        lib: {
            // 打包入口文件, 使用时从入口进行寻找依赖
            entry: resolvePath("src/index.ts"),
            name: "mal-react-components",
            // 打包后文件名 format表示不同的规范(commonjs之类的)
            // 如果打包成 UMD 格式,文件名可能是 mal-vue3-components.umd.js。
            // 如果打包成 ES Module 格式,文件名可能是 mal-vue3-components.es.js
            fileName: format => `mal-react-components.${format}.js`,
        },
    },
})

打包 发布

pnpm build
pnpm publish

使用

在本地想测试, 可以用

# 在库的目录执行
npm link 
# 在要使用的目录中执行
npm link [自己写的库的名称]

但是我之前试了老是失败, 我的解决方法是直接复制打包后的文件到项目中, 然后从其中引入依赖

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java学习笔记】包装类

包装类&#xff08;Wrapper&#xff09; 1. 介绍 &#xff08;1&#xff09;针对八种基本数据类型相应的引用类型 --> 包装类 &#xff08;2&#xff09;有了类的特点&#xff0c;就可以调用类中的方法 2. 分类和继承关系 基本数据类型包装类父类booleanBooleanObjectc…

【高效开发工具系列】Blackmagic Disk Speed Test for Mac:专业硬盘测速工具

博客目录 一、Blackmagic Disk Speed Test 概述二、软件核心功能解析三、v3.3 版本的新特性与改进四、实际应用场景分析五、使用技巧与最佳实践六、与其他工具的比较及优势 一、Blackmagic Disk Speed Test 概述 Blackmagic Disk Speed Test 是 Mac 平台上广受专业人士青睐的一…

UniRig:如何在矩池云一站式解决 3D 模型绑定难题

在 3D 动画制作中&#xff0c;绑定&#xff08;Rigging&#xff09;是一个至关重要但复杂耗时的步骤。它包括为 3D 模型创建骨架并分配蒙皮权重&#xff0c;以实现流畅的动画效果。由清华大学与 Tripo 联合开发的 UniRig 框架&#xff0c;为这一难题提供了全新的解决方案。 什…

字符串字典序最大后缀问题详解

字符串字典序最大后缀问题详解 一、问题定义与背景1.1 问题描述1.2 实际应用场景 二、暴力解法及其局限性2.1 暴力解法思路2.2 代码示例2.3 局限性分析 三、双指针算法&#xff1a;高效解决方案3.1 算法核心思想3.2 算法步骤3.3 代码实现3.4 与暴力解法对比 四、复杂度分析4.1 …

VScode打开后一直显示正在重新激活终端 问题的解决方法

一、问题 本人打开“.py”文件后&#xff0c;同时会出现以下两个问题。 1、VScode一直循环在”正在重新激活终端“ 2、日志显示intellicode报错&#xff1a; Sorry, something went wrong activating IntelliCode support for Python. Please check the “Python” and “VS I…

pe文件结构(TLS)

TLS 什么是TLS? TLS是 Thread Local Storage 的缩写&#xff0c;线程局部存储。主要是为了解决多线程中变量同步的问题 如果需要要一个线程内部的各个函数调用都能访问&#xff0c;但其它线程不能访问的变量&#xff08;被称为static memory local to a thread 线程局部静态变…

中型零售业数据库抉择:MySQL省成本,SQL SERVER?

针对中型零售企业&#xff08;20台固定POS数十台移动POS&#xff0c;含库存管理与结算业务&#xff09;的操作系统与数据库选型&#xff0c;需平衡性能、成本、扩展性及运维效率。结合行业实践与系统需求&#xff0c;建议如下&#xff1a; &#x1f5a5;️ ​​一、操作系统选型…

IDEA中的debug使用技巧

详细教学视频见b站链接&#xff1a;IDEA的debug调试 CSDN详细博客文章链接&#xff1a;debug文章学习 以下为个人学习记录总结&#xff1a; idea中的debug模式界面如下&#xff1a; 现在详细介绍图标作用&#xff1a; 图标一&#xff08;Show Execution Point&#xff09;&…

RockyLinux9.6搭建k8s集群

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

AI IDE 正式上线!通义灵码开箱即用

近期&#xff0c;通义灵码AI IDE正式上线&#xff0c;即日起用户可在通义灵码官网免费下载开箱即用。 作为AI原生的开发环境工具&#xff0c;通义灵码AI IDE深度适配了最新的千问3大模型&#xff0c;并全面集成通义灵码插件能力&#xff0c;具备编程智能体、行间建议预测、行间…

Ubuntu20.04基础配置安装——系统安装(一)

引言&#xff1a; 工作需要&#xff0c;Ubuntu的各类环境配置&#xff0c;从23年开始使用Ubuntu20.04之后&#xff0c;尽管能力在不断提升&#xff0c;但是依旧会遇到Ubuntu系统崩掉的情况&#xff0c;为了方便后续系统出现问题及时替换&#xff0c;减少从网上搜索资源进行基础…

Kafka入门-消费者

消费者 Kafka消费方式&#xff1a;采用pull&#xff08;拉&#xff09;的方式&#xff0c;消费者从broker中主动拉去数据。使用pull的好处就是消费者可以根据自身需求&#xff0c;进行拉取数据&#xff0c;但是坏处就是如果Kafka没有数据&#xff0c;那么消费者可能会陷入循环…

中电金信:从智能应用到全栈AI,大模型如何重构金融业务价值链?

导语 当前&#xff0c;AI大模型技术正加速重构金融行业的智能化图景。为助力金融机构精准把握这一变革机遇&#xff0c;中电金信与IDC联合发布《中国金融大模型发展白皮书》。《白皮书》在梳理了AI大模型整体发展现状的基础上&#xff0c;结合金融行业用户的需求调研深入分析了…

巴西医疗巨头尤迈Kafka数据泄露事件的全过程分析与AI安防策略分析

一、事件背景与主体信息 涉事主体:Unimed,全球最大医疗合作社,巴西医疗行业龙头企业,拥有约1500万客户。技术背景:泄露源于其未保护的Kafka实例(开源实时数据传输平台),用于客户与聊天机器人“Sara”及医生的实时通信。二、时间线梳理 时间节点关键事件描述2025年3月24…

快速上手 Metabase:从安装到高级功能实战

文章目录 1. 引言&#xff1a;Metabase——轻量级的数据分析工具&#x1f3af; 学完本教程你能掌握&#xff1a; 2. 安装 Metabase&#xff1a;本地部署实操2.1 环境准备2.2 使用 Docker 安装 Metabase2.3 初始化设置2.4 连接外部数据库 3. 第一个数据探索&#xff1a;5分钟创建…

Linux基础命令which 和 find 简明指南

&#x1f3af; Linux which 和 find 命令简明指南&#xff1a;从入门到实用 &#x1f4c5; 更新时间&#xff1a;2025年6月7日 &#x1f3f7;️ 标签&#xff1a;Linux | which | find | 命令行 | 文件查找 文章目录 前言&#x1f31f; 一、Linux 命令的本质与 which、find 的作…

思尔芯携手Andes晶心科技,加速先进RISC-V 芯片开发

在RISC-V生态快速发展和应用场景不断拓展的背景下&#xff0c;芯片设计正面临前所未有的复杂度挑战。近日&#xff0c;RISC-V处理器核领先厂商Andes晶心科技与思尔芯&#xff08;S2C&#xff09;达成重要合作&#xff0c;其双核单集群AX45MPV处理器已在思尔芯最新一代原型验证系…

kafka消息积压排查

kafka监控搭建&#xff1a;https://insights.blog.csdn.net/article/details/139129552?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7Ebaidujs_baidulandingword%7EPaidSort-1-139129552-blog-132216491.235%5Ev43%5Econtrol…

drawio 开源免费的流程图绘制

开源地址 docker-compose 一键启动 #This compose file adds draw.io to your stack version: 3.5 services:drawio:image: jgraph/drawiocontainer_name: drawiorestart: unless-stoppedports:- 8081:8080- 8443:8443environment:PUBLIC_DNS: domainORGANISATION_UNIT: unitOR…

YOLOv8 升级之路:主干网络嵌入 SCINet,优化黑暗环境目标检测

文章目录 引言1. 低照度图像检测的挑战1.1 低照度环境对目标检测的影响1.2 传统解决方案的局限性 2. SCINet网络原理2.1 SCINet核心思想2.2 网络架构 3. YOLOv8与SCINet的集成方案3.1 总体架构设计3.2 关键集成代码3.3 训练策略 4. 实验结果与分析4.1 实验设置4.2 性能对比4.3 …