Vite系列课程 | 10. 在 Vite 中处理 CSS

ops/2024/12/28 17:18:05/

10. 在 Vite 中处理 CSS

Vite 内置了对 CSS 的支持,并提供了高效的加载、模块化和热更新机制。

10.1 处理 CSS 文件的过程:从读取到注入
  1. 读取 CSS 文件:

    当 Vite 在 JavaScript 模块中检测到对 CSS 文件的导入(例如 import './index.css'),它会使用 Node.js 的 fs 模块读取该 CSS 文件的内容。

  2. 处理 CSS 内容:

    Vite 在处理 CSS 时,根据开发环境和生产环境采取不同的策略:

    • 开发模式 (动态创建 <style> 标签):

      为了实现快速的热更新,Vite 会将 CSS 内容通过 JavaScript 动态注入到浏览器中:

      1. 创建一个 <style> 标签。
      2. 将 CSS 内容插入到该 <style> 标签中。
      3. <style> 标签动态插入到 HTML 的 <head> 中。

      这种方式的优点是速度快,能够实现即时的样式更新。

    • 转化为 JavaScript 脚本(为了模块化和 HMR):

      为了支持 CSS 模块化和热更新,Vite 会将 CSS 文件转换为 JavaScript 模块。它会设置 Content-Type: application/javascript,告诉浏览器将其作为 JavaScript 文件加载。这个 JavaScript 模块导出一个包含 CSS 样式的字符串。

    • 生产模式优化 (提取到单独的 .css 文件):

      在生产模式下,Vite 会将所有 CSS 文件提取到单独的 .css 文件中,并通过 <link> 标签在 HTML 文件中引入。这种方式有以下优点:

      • 更好的缓存: 浏览器可以单独缓存 CSS 文件,提高页面加载速度。
      • 减少 JavaScript 包体积: 将 CSS 从 JavaScript 包中分离出来,减小 JavaScript 包的体积。
      • 更好的性能: 浏览器可以并行加载 CSS 文件,提高页面渲染速度。

疑问:这里有两种做法,一个是插入到 HTML,一个是转化为 JS 脚本,为什么需要两种方式?区别在哪?

  • 动态创建 <style> 标签并插入 HTML: 主要目的是为了快速应用样式,这是运行时的行为,适用于开发环境,追求速度。
  • 转化为 JavaScript 脚本: 主要目的是为了支持模块化和热更新,这是开发体验的设计,通过将 CSS 封装在 JavaScript 模块中,可以更好地控制样式的应用和更新。
10.2 CSS 模块化:避免样式冲突

为了避免样式命名冲突,尤其是在大型项目和多人协作开发中,Vite 内置了对 CSS 模块化的支持。

10.2.1 原理:生成唯一的类名
  1. 使用 module.css 文件: 文件名以 .module.css 为后缀是一种约定,表示该文件中的 CSS 类名需要进行模块化处理。
  2. 替换类名: Vite 会将原本的类名(例如 .footer)替换成一个独一无二的带 hash 的名称(例如 _footer_i22st_1),以避免命名冲突。
  3. 生成映射对象: Vite 会为替换后的类名创建一个映射对象(例如 { footer: "_footer_i22st_1" }),并将这个对象作为模块的默认导出。
  4. 插入 <style> 标签: Vite 将替换后的 CSS 内容插入到 <style> 标签中,并将其添加到 HTML 的 <head> 中。
  5. JS 脚本替换: 原始的 .module.css 文件会被 Vite 转换成一个 JavaScript 模块,其中包含了替换后的 CSS 内容和映射对象。

针对 CSS 模块化的提问和解答:

  • 如何检测 CSS 文件是模块化的? Vite 通过文件名后缀 .module.css 来识别模块化 CSS 文件。
  • 类名替换为 hash 的实现逻辑是什么? Vite 使用哈希算法(通常是基于文件名和类名生成的短哈希)为每个 CSS 类名生成唯一的 hash 值。这确保了不同模块中即使有相同的类名也不会冲突。
  • 如何生成 CSS 类名的映射对象? Vite 在转换过程中会记录原始类名和生成的 hash 类名之间的对应关系,并将其存储在一个 JavaScript 对象中,然后将该对象作为模块的默认导出。
  • 如何解决类名冲突问题? 通过使用唯一的 hash 值,Vite 确保即使在不同的 CSS 模块中使用相同的类名,最终生成的类名也是不同的,从而避免了冲突。
  • Vite 如何将模块化 CSS 转换为 JavaScript 脚本? Vite 会将 CSS 内容和映射对象封装在一个 JavaScript 模块中,该模块导出一个对象,其中键是原始类名,值是 hash 后的类名。
  • CSS 文件被转换为 JavaScript 脚本后,Vite 如何处理这些文件并将样式插入到页面中? 在开发环境下,这些 JavaScript 模块会被浏览器执行,动态创建 <style> 标签并将 CSS 插入到页面中。

更多关于 CSS 模块化的提问和解答:

  • 如何配置和启用 CSS 模块化? Vite 默认启用了 CSS 模块化,只需要使用 .module.css 后缀的文件名即可。
  • Vite 对 CSS 类名的替换是如何确保唯一性的? Vite 使用哈希算法,结合文件名和类名生成唯一的 hash 值,最大程度地避免冲突。
  • CSS 模块化的 hash 值是如何影响生产环境的性能? hash 的生成对构建时间的影响很小。生产环境下,这些 hash 值有助于浏览器更好地缓存 CSS 文件。
  • Vite 如何处理 CSS Modules 的作用域? CSS Modules 通过 hash 后的类名实现局部作用域,只影响导入该模块的组件。
  • 映射对象的导出方式是什么? 映射对象作为 JavaScript 模块的默认导出。
  • CSS 模块化和样式冲突的管理: 通过唯一的 hash 值避免冲突。
  • Vite 如何保证模块化 CSS 的热更新 (HMR) 性能? Vite 只会更新修改的模块及其相关的样式,不会全页面刷新。
  • CSS Modules 和全局样式的结合: 可以同时使用 CSS Modules 和全局样式。全局样式直接在 CSS 文件中定义,不使用 .module.css 后缀。
  • 如何调试和查看模块化 CSS 的生成过程? 可以使用浏览器的开发者工具查看生成的 HTML 和 CSS,以及 JavaScript 模块中导出的映射对象。
  • Vite 中的 CSS 模块化是否支持其他 CSS 预处理器? 支持,例如 Sass、Less、Stylus 等。只需要安装相应的预处理器,Vite 会自动处理。
10.3 使用 Less(预处理器):扩展 CSS 功能

Vite 支持 CSS 预处理器,如 Less、Sass、Stylus 等。要使用 Less,需要先安装:

npm install less --save-dev
# 或使用 yarn / pnpm
yarn add less -D
pnpm add less -D

安装后,就可以在项目中使用 Less 文件(.less 后缀),Vite 会自动编译它们。

10.4 总结:提高开发效率和代码质量

Vite 的 CSS 处理方式通过内置的模块化和动态脚本替换机制,提高了开发体验,尤其是在多人协作时避免了样式冲突。同时,借助预处理器(如 Less)的支持,开发者可以更灵活地管理和使用样式。

10.5 npm i -ynpm i 的区别
  • npm i:安装依赖,可能会提示用户进行确认(例如,安装 peerDependencies)。
  • npm i -y:安装依赖,自动确认所有提示,无需用户交互。

通过以上更详细的解释和对问题的解答,相信你对 Vite 如何处理 CSS 文件有了更深入的理解。


http://www.ppmy.cn/ops/145702.html

相关文章

【FPGA】ISE13.4操作手册,新建工程示例

关注作者了解更多 我的其他CSDN专栏 求职面试 大学英语 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处…

解决 vue3 中 echarts图表在el-dialog中显示问题

原因&#xff1a; 第一次点开不显示图表&#xff0c;第二次点开虽然显示图表&#xff0c;但是图表挤在一起&#xff0c;页面检查发现宽高只有100px,但是明明已经设置样式宽高100% 这可能是由于 el-dialog 还没有完全渲染完成&#xff0c;而你的 echarts 组件已经开始尝试渲染图…

NSSCTF-web刷题

[UUCTF 2022 新生赛]ez_upload Apache解析漏洞&#xff0c;apache cve2017 重点是把文件名改为1.jpg.php就可以将图片解析为php&#xff0c;很抽象&#xff0c;这个洞 蚁剑直接连 [SWPUCTF 2022 新生赛]ez_1zpop <?php error_reporting(0); class dxg { function fmm() {…

频繁拿下定点,华玉高性能中间件迈入商业化新阶段

伴随着智能驾驶渗透率的快速增长&#xff0c;中国基础软件市场开始进入黄金窗口期。 近日&#xff0c;华玉通软&#xff08;下称“华玉”&#xff09;正式获得某国内头部轨道交通产业集团的智能化中间件平台定点项目。这将是华玉在基础软件领域深耕和商业化发展过程中的又一重…

如何保护你的 iOS 应用免受逆向工程攻击

逆向工程是分析和解构软件以理解其工作原理的过程。针对 iOS 应用&#xff0c;逆向工程通常涉及分析已编译的二进制文件&#xff08;机器可读的代码&#xff09;&#xff0c;并将其转化为更容易被人类理解的形式。这使得攻击者能够检查应用的逻辑、理解数据处理的方式&#xff…

uniappX 移动端单行/多行文字隐藏显示省略号

在手机端不能多行省略使用 -webkit-line-clamp 属性所以移动端多行省略不会生效改为 lines 属性即可 /**单行文本溢出显示省略号*/ .text-ov1 {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;height: auto; } /**APP多行文本溢出显示省略号*/ // #ifdef APP-…

电脑ip地址会变化吗?电脑ip地址如何固定

在数字化时代&#xff0c;IP地址作为网络设备的唯一标识符&#xff0c;对于网络通信至关重要。然而&#xff0c;许多用户可能会发现&#xff0c;自己的电脑IP地址并非一成不变&#xff0c;而是会随着时间的推移或网络环境的变化而发生变化。这种变化有时会给用户带来困扰&#…

《Ceph:一个可扩展、高性能的分布式文件系统》

大家觉得有意义和帮助记得及时关注和点赞!!! 和大多数分布式存储系统只支持单一的存储类型不同&#xff0c;Ceph 同时支持三种&#xff1a; 文件系统&#xff08;file system&#xff09;&#xff1a;有类似本地文件系统的层级结构&#xff08;目录树&#xff09;&#xff0c…