tailwindcss 多上下文与独立分包

news2024/11/25 15:42:46

Image

tailwindcss 多上下文与独立分包

你看过动漫《百兽王》吗?《百兽王》的主人公是五个飞行员,他们分别驾驶黑、红、青、黄、绿五头机器狮,它们平时可以单独进行作战,遇到强敌时,也能进行五狮合体,成为巨大机器人“百兽王”。

同样,在日常开发中,我们经常遇到这样的问题,一个很大的程序,它有很多个独立的部分组成,每一个部分可以单独运行,也有独立的入口,相互之间没有任何的依赖,但是它们在同一个项目/任务里进行构建。

在这种场景下,去使用 tailwindcss 就往往需要去创建多个上下文,让这些上下文各自去管理我们程序中的指定的一块区域。

当然我写到这,相信大家也啥都没看懂,于是我搬出一个小程序中,独立分包的示例,来让大家理解这种思想。

什么是独立分包

独立分包是小程序中一种特殊类型的分包,可以独立于主包和其他分包运行。从独立分包中页面进入小程序时,不需要下载主包。当用户进入普通分包或主包内页面时,主包才会被下载。

独立分包属于分包的一种。普通分包的所有限制都对独立分包有效。独立分包中插件、自定义组件的处理方式同普通分包。此外,使用独立分包时要注意:

  1. 独立分包中不能依赖主包和其他分包中的内容,包括 js 文件、template、wxss、自定义组件、插件等(使用 分包异步化 时 js 文件、自定义组件、插件不受此条限制)
  2. 主包中的 app.wxss 对独立分包无效,应避免在独立分包页面中使用 app.wxss 中的样式;
  3. App 只能在主包内定义,独立分包中不能定义 App,会造成无法预期的行为;
  4. 独立分包中暂时不支持使用插件。

更多信息详见 微信独立分包官方文档


这里要特别注意第二条: 主包中的 app.wxss 对独立分包是无效的!!!

在我之前提供的tailwindcss小程序模板的示例中,所有 tailwindcss 生成的 wxss 工具类都是在主包里共用的 (app.wxss),这在大部分情况下运转良好,然而这在独立分包场景下,是不行的!因为主包的样式无法影响到独立分包。

那么应该怎么做才能解决这个问题呢?

创建与配置示例

这里笔者先以 taro@3.6.7weapp-tailwindcss@2.5.2 版本的项目作为示例。

首先配置好 weapp-tailwindcss 的配置,然后在 config/index.js 中关闭 prebundle 功能,因为这在独立分包场景下会报一些未知的错误:

const config = {
  compiler: {
    prebundle: {
      enable: false,
    },
    type: 'webpack5'
  },
  // .....
}

其次关闭插件对 tailwindcss css var 主块的寻址行为:

chain.merge({
  plugin: {
    install: {
      plugin: UnifiedWebpackPluginV5,
      args: [{
        // 方法1: 不要传 appType
        // 注释掉 appType : 'taro'
        // 或者方法2: 让所有css chunk 都是 main chunk
        // mainCssChunkMatcher: ()=> true
        // 2 种选其一即可
      }]
    }
  }
})

接下来我们就可以创建一个独立分包 moduleA,在里面新建一个 "pages/index" 页面,并写入一个只属于 moduleA 的独一无二的 tailwindcss class,然后在 app.config.ts 里注册它:

  subpackages: [
    {
      root: "moduleA",
      pages: [
        "pages/index",
      ],
      // 下方这个标志位,声明独立分包
      independent: true
    },
  ]

到这里,准备工作就完成了,接下来就可以设计方案了。

tailwindcss 上下文的方案(不完美不推荐)

这个方案是一个不完美的方案,在这里写出来是为了促进大家对 tailwindcss 的理解。

首先在独立分包中,也创建一个 index.scss 内容为:

@import 'tailwindcss/base';
@import 'tailwindcss/utilities';

然后在所有独立分包中的页面引用它,这样打包之后,独立分包里的 tailwindcss 样式也就生效了。

然而这种方式有一个巨大的问题,就是它会带来严重的 css 冗余。

因为此时 tailwindcss 上下文有且仅有一个,它会把在这个项目中,所有提取出来的 css 工具类,全部注入到所有的 @tailwind 指令里去。@import 'tailwindcss/utilities' 这个引入(本质实际上是@tailwind指令)一下子膨胀了起来。

这导致了,主包里的 app.wxss 里,会包含主包里所有的 class + 独立分包里所有的 class,而独立分包里的 index.scss 里,也包含主包里所有的 class + 独立分包里所有的 class!

这显然是不可接受的,因为主包是没有必要包含独立分包的 class,而独立分包里,也没有必要包含主包里的 class! 这只会白白增大打包后wxss文件的体积。

所以这个方案需要改进!

tailwindcss 上下文的方案

由于上面那个方案的问题,我们开始改进,就必须要创建多个 tailwindcss 上下文。

那么第一步就是要

创建多个 tailwind.config.js

比如说我们只有一个独立分包,所以我们创建了2个 tailwind.config.js:

  1. tailwind.config.js 用于主包以及相互依赖的子包
  2. tailwind.config.sub.js 用于 moduleA 这个独立分包

内容如下:

独立分包的上下文配置

// `moduleA` 这个独立分包的 tailwind.config.sub.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  // 这里只提取 moduleA 这个独立分包下的文件内容
  content: ["./src/moduleA/**/*.{html,js,ts,jsx,tsx}"],
  // ....
  corePlugins: {
    preflight: false
  }
}

主包以及相互依赖的子包的上下文配置

// 主包以及相互依赖的子包的 tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  // https://github.com/mrmlnc/fast-glob
  // 这里需要限定范围,不去提取 moduleA 这个独立分包下的文件内容
  // 所以后面跟了一个 `!` 开头的路径
  content: [
    "./src/**/*.{html,js,ts,jsx,tsx}", 
    // 不提取独立分包里的 class
    "!./src/moduleA/**/*.{html,js,ts,jsx,tsx}"],
  // ....
  corePlugins: {
    preflight: false
  }
}

这样 2 个配置文件创建好了,接下来就要通过配置让它们各自在打包中生效。

postcss.config.js 配置

这是非常重要的一块配置,我们需要把 postcss.config.js 的配置变成一个函数,这样才能把构建时的上下文传入进来:

const path = require('path')

module.exports = function config(loaderContext) {
  // moduleA 下面的所有 scss 文件,都是独立模块的,应用不同的 tailwindcss 配置
  const isModuleA = /moduleA[/\\](?:\w+[/\\])*\w+\.scss$/.test(
    loaderContext.file
  )
  // 多个独立子包同理,加条件分支即可
  if (isModuleA) {
    return {
      plugins: {
        tailwindcss: {
          config: path.resolve(__dirname, 'tailwind.config.sub.js')
        },
        autoprefixer: {},
      }
    }
  }
  
  return {
    plugins: {
      // 不传默认取 tailwind.config.js
      tailwindcss: {},
      autoprefixer: {},
    }
  }
}

通过这种方式,我们成功的创建了 2 个不同的 tailwindcss 上下文,此时你进行打包之后,会发现

主包里的 app.wxss 和独立分包里的 index.wxss,里面的内容就已经各归各了,不再相互包含了。

尾言

当然,上面只是一种方案,达到这样的目的方式有很多种,比如你可以在运行时去修改 postcss-loader 对它进行劫持,或者拆成多个项目,分开构建。

我这篇文章只是抛砖引玉,相信聪明的你们一定可以举一反三的。

参考示例

示例见:https://github.com/sonofmagic/weapp-tailwindcss/tree/main/demo/taro-app

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

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

相关文章

论文写作全攻略

【基于Citespace和vosviewer文献计量学相关论文 】 文献计量学是指用数学和统计学的方法,定量地分析一切知识载体的交叉科学。它是集数学、统计学、文献学为一体,注重量化的综合性知识体系。特别是,信息可视化技术手段和方法的运用&#xff0…

uniapp写出文本域,右下角并限制字数200

<view class"textarea_box"><textarea class"textarea" placeholder"请填写10字以上的问题描述&#xff0c;以便我们更好的帮助您解决问题&#xff0c;提高产品质量。" placeholder-style"font-size:28rpx" maxlength"2…

图片怎么压缩到200K以内?来试试这几种压缩方法

怎么把图片压缩到200K以内呢&#xff1f;在日常生活中&#xff0c;不管是工作还是出门游玩&#xff0c;都会使用图片&#xff0c;当这些图片的内存太大时&#xff0c;保存和发送会成为一种难题&#xff0c;有的网站甚至无法上传超过一定内存的照片&#xff0c;那么我们怎么给照…

组态王与FX5u之间EtherNet/IP无线以太网通信

在实际系统中&#xff0c;同一个车间里分布多台PLC&#xff0c;通过上位机集中控制。通常所有设备距离在几十米到上百米不等。在有通讯需求的时候&#xff0c;如果布线的话&#xff0c;工程量较大耽误工期&#xff0c;这种情况下比较适合采用无线通信方式。 本方案以组态王和2…

磨刀不误砍柴工,五款让你事半功倍的软件

有句老话这样讲&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;好的工具可以让你工作起来事半功倍。 网页收藏夹——Pocket Pocket是一款用于保存和阅读网页的工具。它可以让你把你感兴趣的网页保存到你的账户中&#xff0c;并提供多种功能和选项来优化你的阅读体…

PHP初中英语在线考试系统的设计与实现-计算机毕设 附源码87564

PHP初中英语在线考试系统的设计与实现 摘 要 本文研究的初中英语在线考试系统主要功能模块包括&#xff1a;学生用户管理、考试信息、成绩分析、通知公告管理&#xff0c;采取面对对象的开发模式进行软件的开发和硬体的架设&#xff0c;能很好的满足实际使用的需求&#xff0c;…

【深度学习】4-2 误差反向传播法 - 简单层的实现(层的介绍)

下面把构建神经网络的“层”实现为一个类。这里所说的“层”是神经网络中功能的单位。 下面先从一些简单的层开始介绍 乘法层的实现 层的实现中有两个共通的方法(接口)forward()和backward()。 forward() 对应正向传播 backward() 对应反向传播 现在来实现乘法层。看下面代…

SpringBoot 如何使用 Servlet 容器

SpringBoot 如何使用 Servlet 容器 SpringBoot 是一个非常流行的 Java 开发框架&#xff0c;它提供了一个简单而强大的方式来创建基于 Servlet 容器的 Web 应用程序。本文将介绍 SpringBoot 中如何使用 Servlet 容器。 Servlet 容器简介 Servlet 容器是指能够运行 Servlet 和…

一文带你认识FPGA LCMXO2-7000HC-4FG484C 带你深入了解其原理及特点

莱迪思深力科 LCMXO2-7000HC-4FG484C MachXO2系列 可编程逻辑器件 (PLD) 由六个超低功耗、即时启动、非易失性 PLD 组成&#xff0c;可提供 256 至 6864 个查找表 (LUT) 的密度。MachXO2 系列 PLD 提供多种特性&#xff0c;例如嵌入式块 RAM (EBR)、分布式 RAM 和用户闪存 (UFM…

linux端口数量上限65535原因;linux服务端最大连接数量可以超过65535

概述 关于端口数量&#xff0c;大家都知道最多是65535个端口。 这个来源于标识端口号的变量是16位的&#xff0c;那么就是65536个&#xff0c;去掉0这个特殊端口&#xff0c;剩下65535个&#xff0c;所以理论上最大可用数量是65535。 但是实际中还有一些特殊端口已经定义好用…

sourceTree代码回滚

记一次惊心动魄的代码回滚记录&#xff01; 背景&#xff1a; 因为test分支进行Jenkins代码构建的时候发现文件引入的两个已安装的依赖没有找到&#xff0c;构建报错 可是我明明已经安装成功&#xff0c;并且package.json中也有了版本记录&#xff0c;可就是构建失败&#xf…

面试官:“同学,你做的这几个项目都不错。但怎么问QPS你就胡说呢?”

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 这位同学&#xff0c;你比上一位面试者好多了&#xff0c;你的简历中做的几个项目都不错。既有业务项目&#xff0c;也有技术项目…

电子签名软件有哪些?10大电子签名平台盘点

目录 一、电子签名软件有哪些 1.e签宝&#xff1a;国内签名领域老大哥 2.上上签&#xff1a;开创SaaS电子签极简模式 3.法大大&#xff1a;数智化签约管理平台 4.数字认证&#xff1a;中国电子认证第一股 5.契约锁&#xff1a;主攻中大型客户无缝集成各类系统 6.安心签&…

持有NPDP产品经理证书可以加薪吗?

NPDP(New Product Development Professional)是指产品经理国际资格认证&#xff0c;由美国产品开发与管理协会&#xff08;PDMA&#xff09;所发起的唯一国际公认新产品开发专业认证。NPDP是集理论、方法与实践为一体的全方位知识体系&#xff0c;为公司组织层级进行规划、决策…

破圈丨2023年绿色积分消费返利:云联惠3.0升级版【循环购】商业模式

破圈丨2023年绿色积分消费返利&#xff1a;云联惠3.0升级版【循环购】商业模式 京东供应链商品/自营商品/供应商商品 平台上面产品超过300w款产品&#xff0c;均为京东供应链货品&#xff0c;由京东统一仓储和配送&#xff0c;从源头上面杜绝假冒伪劣产品的存在&#xff0c;然…

AI绘图是什么技术?前景如何?

大家好&#xff0c;我是权知星球&#xff0c;人工智能最近大火&#xff0c;各大应用领域层出不穷&#xff0c;今天跟大家讨论一下AI绘图是什么技术&#xff1f;前景如何&#xff1f; 人工智能绘图是什么&#xff1f; 人工智能绘画是指利用人工智能进行绘画的过程&#xff0c;属…

redhat 6.4安装oracle11g RAC (三)

为数据和快速恢复去创建ASM磁盘组 只在节点rac1执行即可&#xff0c;进入grid用户下 [gridrac1 grid]$ srvctl status asm -a ASM is running on rac2,rac1 ASM is enabled. [gridrac1 grid]$ ps -ef|grep lsnr|grep -v grep|grep -v ocfs|awk {print$9} LISTENER_SCAN1 LISTE…

Databend 开源周报 第 98 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.cn 。 Whats On In Databend 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 后台服务 Dat…

强化学习从基础到进阶-案例与实践[2]:马尔科夫决策、贝尔曼方程、动态规划、策略价值迭代

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

zerotier自建planet

ZeroTier 是一个由 C 开发的软交换机&#xff0c;可以让多台内网机器组成一个私有的局域网。ZeroTier 的节点分为三类&#xff1a; Planet Server: 官方的根服务器&#xff0c;用于记录和配置每个局域网下客户端信息&#xff08;以下简称 Planet&#xff09;&#xff1b;Moon …