使用tailwindcss来构建以及引入外部组件

news2024/10/6 1:39:38

Image

使用tailwindcss来构建以及引入外部组件

  • 使用tailwindcss来构建以及引入外部组件
    • 前言
    • 构建组件
      • 核心思想
      • 可行方案
      • 不可行方案
    • 可行方案详解
      • custom css selector + Functions & Directives
      • add prefix
      • add scoped
      • 不打包
    • 构建demo链接
    • 相关issues

前言

我们在日常的开发中,经常会去使用和封装各种各样的组件库。有些是开源的,第三方开发的UI库,有些是我们开发人员给自己的特定的业务封装的UI库。其中很多情况其实是以流行的 开源UI库(或者fork的改版) + 自己封装的业务组件为主的

开源UI库 它们的样式相对来说是独立于整套系统的,比如它们的样式都是 ant-el- 开头的,一般引入之后不会和原先系统里的样式产生冲突。而 自己封装的业务组件,由于往往和系统高度绑定也没有这样的问题。

那么如何用 tailwindcss 来构建/发布和引入自己封装的业务组件呢?

构建组件

核心思想

首先我必须重点把本篇文章的核心思想预先抛出:

tailwindcss 只是一个css生成器,它只是帮你按照一定的规则,从你的源代码中匹配字符串去生成css。所以在用它去构建组件的时候,一定要去思考你用 tailwindcss 生成的 css 的影响范围,因为大部分用 tailwindcss 都是默认全局应用的。但是你在组件里面的自定义样式很多情况下,是没有必要的。

根据这个核心思想,我们就可以知道在封装组件时可行和不可行的方式了,大致如下:

可行方案

  1. custom css selector + Functions & Directives
  2. add prefix (添加前缀)
  3. add scoped (像 vuescoped 一样添加 data-v-[hash] 类似的自定义属性,然后去修改css选择器)
  4. 不打包方案 (不构建产物,直接发布,然后在项目里安装,再提取 node_modules 里制定的文本重新生成。)

不可行方案

  1. module css 这会去修改 css 选择器。

可行方案详解

这里我写了2个demo分别是 reactvue,其中下方代码以 vue 为示例,react示例见下方的 构建demo链接

custom css selector + Functions & Directives

这种方案其实非常的传统,仅仅使用到了 tailwindcss@applytheme 等等指令的功能。

比如我们有个组件 ApplyButton.vue,它的模板,样式和独立的 tailwind.config.js 分别如下所示:

<script setup lang="ts">
</script>

<template>
  <button class="apply-button">ApplyButton</button>
</template>

<style src="./index.css"></style>
@config 'tailwind.config.js';
@tailwind utilities;

.apply-button {
  @apply text-white p-4 rounded;
  background-color: theme("colors.sky.600")
}
const path = require('node:path')

/** @type {import('tailwindcss').Config} */
export default {
  content: [path.resolve(__dirname, './index.vue')],
  // ...
}

然后在打包的时候,以这个文件或者导出文件(index.ts) 为打包入口即可。

这样它的产物css中,选择器由于是你自己定义的,就能尽可能保证它是独一无二的。

它对应的css产物为:

.apply-button {
  border-radius: 0.25rem;
  --tw-bg-opacity: 1;
  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
  padding: 1rem;
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity));
}

add prefix

这个也很好理解,前缀嘛,各个UI库都是这样搞的,我们就可以创建出以下的代码:

<script setup lang="ts">
</script>

<template>
  <button class="ice-bg-sky-600 ice-text-white ice-p-4 ice-rounded">PrefixButton</button>
</template>

<style>
@config 'tailwind.config.js';
@tailwind utilities;
</style>
const path = require('node:path')

/** @type {import('tailwindcss').Config} */
export default {
  prefix: 'ice-',
  content: [path.resolve(__dirname, './index.vue')],
}

它对应的css产物为:

.ice-rounded {
  border-radius: 0.25rem;
}
.ice-bg-sky-600 {
  --tw-bg-opacity: 1;
  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
}
.ice-p-4 {
  padding: 1rem;
}
.ice-text-white {
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity));
}

add scoped

这个就是通过同时添加html标签属性和修改css选择器来做的了:

<script setup lang="ts">
</script>

<template>
  <button class="bg-sky-600 text-white p-4 rounded">ScopedButton</button>
</template>

<style scoped>
@config 'tailwind.config.js';
@tailwind utilities;
</style>

这里仅仅给 style 加了一个 scoped 属性

const path = require('node:path')

/** @type {import('tailwindcss').Config} */
export default {
  content: [path.resolve(__dirname, './index.vue')],
}

css 生成结果为:

.rounded[data-v-10205a53] {
  border-radius: 0.25rem;
}
.bg-sky-600[data-v-10205a53] {
  --tw-bg-opacity: 1;
  background-color: rgb(2 132 199 / var(--tw-bg-opacity));
}
.p-4[data-v-10205a53] {
  padding: 1rem;
}
.text-white[data-v-10205a53] {
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity));
}

不打包

以上三种方式总结一下,都是通过在选择器上下功夫来制作组件库的,而且它们都有一个打包的过程,即 src->dist 然后发布 dist

可是这第四种方案就不怎么一样了: 核心就是 不打包

即我们写好组件之后,直接把 npm的入口文件,指向 src ,然后直接把里面的组件发布(比如直接发布 vue组件)

这种情况下,你需要让你在 node_modules 里的组件再次经受一遍 js 的处理,比如 vue sfc compiler,babel,swc等等。

同时你也需要配置你项目里的 tailwind.config.js 去提取你 node_modules 里的组件源代码内容:

module.exports = {
  content: [
    './index.html',
    './src/**/*.{html,js,ts,jsx,tsx,vue}',
+   './node_modules/mypkg/src/components/**/*.{html,js,ts,jsx,tsx,vue}'
  ]
}

这样才能重新提取生成 css 在项目主css chunk里。

构建demo链接

https://github.com/sonofmagic/weapp-tailwindcss/tree/main/how-to-build-components-by-tailwindcss

相关issues

https://github.com/sonofmagic/weapp-tailwindcss/issues/247

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

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

相关文章

cv2.split函数与cv2.merge函数

split函数用于图像BGR通道的分离 merge函数用于可将分开的图像通道合并到一起 1.split函数的使用 这是原图&#xff0c;我们使用split函数对其三个通道进行分离。 注意&#xff1a;split函数分离通道的顺序是B、G、R。 以下方法是将三个通道的值都设置为与某一个通道相同。…

AI工程化—— 如何让AI在企业多快好省的落地?

文章目录 前言内容简介读者对象专家推荐目录赠书活动 前言 作为计算机科学的一个重要领域&#xff0c;机器学习也是目前人工智能领域非常活跃的分支之一。机器学习通过分析海量数据、总结规律&#xff0c;帮助人们解决众多实际问题。随着机器学习技术的发展&#xff0c;越来越多…

asp.net+mvc+三层架构core企业员工考勤签到系统 mysql办公设备借用管理系统vue

系统中的核心员工是系统管理员&#xff0c;管理员登录后&#xff0c;通过管理员菜单来管理后台系统。主要功能有&#xff1a;管理员&#xff1a;个人中心、员工信息管理、留言板管理、系统管理、签到平台管理、签到信息管理、请假平台管理、办公设备管理、设备申请信息管理、请…

Flutter开发笔记 —— 语音消息功能实现

前言 最近在开发一款即时通讯(IM)的聊天App&#xff0c;在实现语音消息功能模块后&#xff0c;写下该文章以做记录。 注&#xff1a;本文不提供相关图片资源以及IM聊天中具体实现代码&#xff0c;单论语音功能实现思路 需求分析 比起上来直接贴代码&#xff0c;我们先来逐步…

day10_复习_数组_方法

非常重要的: 方法设计(参数,返回值,调用) 数组也重要,但是后续很少用! 是因为后期有更简单的【集合】&#xff0c;重要在于是一种思想&#xff0c;也是一种代码逻辑 关于数组: 声明创建取值,存值遍历面试|算法 --> 排序内存图(堆,栈,引用) 今天 数组工具类:Arrays数组扩容(拷…

Linux服务器报错“No space left on device”如何解决

一、错误的含义&#xff0c;说明在服务器设备上的存储空间已经满了&#xff0c;不能再上传或者新建文件夹或者文件等。 二、确认查看服务器系统的磁盘使用情况是否是真的已经没有剩余空间&#xff0c;复制下面命令在服务器上运行&#xff0c;然后发现如果如下图所示那么表明sda…

Unsafe概述

前言 ​ 如果看过Java并发包里面的源码、或者netty网络通讯相关源码&#xff0c;就会到Unsafe类有一定的了解。这个与其的特性有关。 介绍 ​ **Unsafe是位于sun.misc包下的一个类&#xff0c;主要提供一些用于执行低级别、不安全操作的方法&#xff0c;如直接访问系统内存资…

《DevOps 精要:业务视角》- 读书笔记(三)

DevOps 精要:业务视角&#xff08;三&#xff09; 第3章 原则3.1 价值流3.2 部署流水线3.3 一切都应存储在版本控制系统中3.4 自动化配置管理3.5 完成的定义3.6 小结 第3章 原则 将原则从实践中分离出来&#xff0c;这是一种很有用的做法。当然了&#xff0c;这两个词分别有着…

CCF中国开源大会专访|毛晓光:“联合”是开源走向“共赢”的必由之路

受访嘉宾 | 毛晓光 记者 | 朱珂欣 2023 CCF 中国开源大会&#xff08; CCF ChinaOSC &#xff09;拟于 2023 年 10 月 21 日至 22 日在湖南省长沙市北辰国际会议中心召开。 作为第二届 CCF 中国开源大会&#xff0c;本届大会将组织特邀报告、高峰论坛和领域分论坛等不同类…

防御安全第四次作业

1. 什么是APT&#xff1f; APT全称&#xff1a;Advanced Persistent Threat 高级可持续威胁攻击。 指的是某组织对特定对象展开持续有效的攻击活动。 这种攻击活动具有极强的隐蔽性和针对性&#xff0c;通常会运用受感染的各种介质&#xff0c;供应链和社会工程学等手段&#x…

Kafka 架构

正文 一、Kafka的架构 如上图所示&#xff0c;一个典型的Kafka集群中包含若干Producer&#xff08;可以是web前端产生的Page View&#xff0c;或者是服务器日志&#xff0c;系统CPU、Memory等&#xff09;&#xff0c;若干broker&#xff08;Kafka支持水平扩展&#xff0c;一般…

解决 Jenkins 性能缓慢的问题~转

解决 Jenkins 性能缓慢的问题 Docker中文社区 ​​ 计算机技术与软件专业技术资格持证人 2 人赞同了该文章 没有什么比缓慢的持续集成系统更令人沮丧的了。它减慢了反馈循环并阻止代码快速投入生产。虽然像使用性能更好的服务器可以为您争取时间&#xff0c;但您最终必须投资…

AdaBoost(上):数据分析 | 数据挖掘 | 十大算法之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

张量-复数操作函数

tf.complex(real,imag,name None),该函数用于将两实数转化为复数。 示例代码如下: import tensorflow.compat.v1 as tf tf.disable_v2_behavior()real tf.constant([2.25,3.25],dtype tf.float64) imag tf.constant([4.75,5.75],dtype tf.float64)with tf.Session() as …

Bigemap中如何添加21级的影像图

工具 Bigemap gis office地图软件 BIGEMAP GIS Office-全能版 Bigemap APP_卫星地图APP_高清卫星地图APP 很多人在咨询如何查看21级的影像图 这里先来说一下影像的像素分辨率&#xff0c;一般17级是1米的、18级是0.5米、19级是0.25米以此类推&#xff0c;咱们国家测绘要求允…

HTTP/2和HTTP/3简介(上)(下)【中科大-郑烇老师】

文章目录 我的总结&#xff1a;HTTP 1.0HTTP 1.0 支持 多个并行连接HTTP 1.1 持久连接&#xff08;非流水线和流水线&#xff09; HTTP/2HTTP /3HTTP的演化 from &#xff1a; https://www.bilibili.com/video/BV1R34y1G76h/?spm_id_from333.788&vd_source21cce77bb69d40a…

Zookeeper经典应用场景实战(二)

文章目录 1、 Zookeeper 分布式锁实战1.1、 什么是分布式锁1.2、 基于数据库设计思路1.3、 基于Zookeeper设计思路一1.4、 基于Zookeeper设计思路二 1、 Zookeeper 分布式锁实战 1.1、 什么是分布式锁 在单体的应用开发场景中涉及并发同步的时候&#xff0c;大家往往采用Sync…

Bootstrap对段落和文本的设置(与段落-和文本相关的类)

目录 01-利用lead类突出显示段落文本02-为段落添加强调样式03-给段落文字添加鼠标停留时的说明语04-添加引用信息05-文本对齐(左对齐、居中对齐、右对齐、两端对齐)06-阻止文本换行07-以省略号显示溢出的文本内容08-转换文本内容中字母的大小写09-设置文本字体的粗细和斜体10-取…

The Sandbox 与 TB Media Global 达成合作

这家总部位于泰国的公司以开发原创、适合家庭观看的内容而闻名&#xff0c;将在 The Sandbox 中推出新的虚拟体验。 备受赞誉的 IP 开发公司 T&B Media Global 正式加入 The Sandbox 元宇宙。该公司以专注于故事讲述艺术而闻名。这次合作不仅为虚拟世界带来了新的维度&…

java常见API----indexof

API indexof API toUpperCase()用法及实例&#xff1a; package daysreplace;import java.util.Locale;public class IndexofApiTest {public static void main(String[] args) {String str "nanyanghhhhh";String bigStr "KKKKAAAAHHHH";System.…