lightningcss介绍及使用

lightningcss介绍及使用

一款使用 rust 编写的 css 解析器,转换器、及压缩器。

特性

  • 特别快:可以在毫秒级别解析、压缩大量的 css 文件,而且比其他工具的打包结果更小
  • 给值添加类型:许多其他css解析器会将值解析成一个无类型的 tokens,这也就意味着每个转换器如果想要操作这些值就需要手动侵入他们,造成重复工作及不统一性。而 lightningcss 遵循 css 的语法规范,给每个值提供了一个规范的类型。
  • 基于浏览器的解析器:lightningcss 是在 cssParser 和 selectors 基础上创建的(这俩工具都是由 Mozilla 创建,被 Firefox 和 Servo 使用),基于它们提供的有效、通用的 css 解析,lightningcss 实现了全部的 css 规格及属性。
  • 压缩:lightningcss 其中一个主要功能就是压缩 css,使其变得更小,包括以下几点优化:
    • 尽可能将常规写法的属性编写简写
    • 在安全情况下将相同选择器或者声明中的规则进行合并
    • 根据提供的浏览器类型删除多余的前缀
    • 尽可能减少 calc 表达式
    • 尽可能将 colors 值转换成十六进制格式
    • 压缩 gradient 属性
    • 压缩 css grid
    • 值排序
    • 拥有许多细节优化,比如:转换成更短的单位,移除非必要的引号等
  • 浏览器前缀:跟其他 css 编译器一样支持自动添加浏览器前缀
  • 浏览器配置:支持浏览器列表配置
  • 语法降级:只能最新的css语法,并能够根据浏览器目标进行适配
    • css 嵌套
    • 常规的媒体查询
    • 逻辑值
    • Color level 5
      • color-mix() 函数
      • 相对颜色语法:lab(from purple calc(l * .8) a b)
    • Color lever 4
      • lab,lch、oklab、oklch 这些颜色格式
    • 选择器
      • :not、:lang、:dir、:is
  • css 模块:支持 css modules 的特性
  • 自定义转换器:支持通过插件的方法自定义转换器插件

安装

npm i lightningcss -D

api

不同 api 打包的结果不同。

示例结构:

  • index.css(导入 body.css)
  • body.css
/* index.css */
@import url('./body.css');a,
.link {color: red;
}
a:hover {color: blue;
}/* body.css */
body {background: rgb(157, 177, 88);
}

transform

编译一个 css 文件,可以配置压缩、语法降级、sourcemap 生成(默认不生成)等。

import * as lightningcss from "lightningcss";
import fs from "node:fs/promises";async function getCssContent() {const content = await fs.readFile("./index.css", "utf-8");return content;
}async function transform() {const file = await getCssContent();let result = await lightningcss.transform({code: Buffer.from(file),});return result;
}transform().then(res => {console.log(res)
})
// {
//  code: <Buffer 40 69 6d 70 6f 72 74 20 22 2e 2f 62 6f 64 79 2e 63 73 73 22 3b 0a 0a 61 2c 20 2e 6c 69 6e 6b 20 7b 0a 20 20 63 6f 6c 6f 72 3a 20 72 65 64 3b 0a 7d 0a ... 28 more bytes>,
//  map: null,
//  exports: null,
//  references: null,
//  dependencies: null,
//  warnings: []
// }

可以看到返回的结果中 code 也是 Buffer,需要调用 toString() 方法转换成字符串。

res.code.toString();
// @import "./body.css";// a, .link {
//   color: red;
// }// a:hover {
//   color: #00f;
// }

该方法并不会直接解析出 @import 导入的 css 文件内容,也没有任何关于导入文件信息,如果我们要分析导入文件,需要传递 analyzeDependencies: true

此时在 dependencies 字段中就会有相关的信息:

// {
//  code: <Buffer 40 69 6d 70 6f 72 74 20 22 2e 2f 62 6f 64 79 2e 63 73 73 22 3b 0a 0a 61 2c 20 2e 6c 69 6e 6b 20 7b 0a 20 20 63 6f 6c 6f 72 3a 20 72 65 64 3b 0a 7d 0a ... 28 more bytes>,
//  map: null,
//  exports: null,
//  references: null,
//  dependencies: [
//    {
//      type: 'import',
//      url: './body.css',
//      placeholder: '2PNO-q',
//      supports: null,
//      media: null,
//      loc: {
//        filePath: ''
//        start: { line: 1, column: 9 },
//        end: { line: 1, column: 20 }
//      }
//    }
//  ],
//  warnings: []
// }

需要注意以下上面 dependencies 中的 placeholder 字段,它是一个占位符,可以通过这个占位符将生成的文件名进行更改:

transformStyleAttribute

编译单个文件,比如说 html 中的内联 css。使用这个 api 时能不能携带 @import

async function transform() {const file = await getCssContent();let result = await lightningcss.transformStyleAttribute({code: Buffer.from(file),});return result;
}transform().then((res) => {console.log(res.code.toString());
});
// SyntaxError: Unknown at rule: @import

由于 index.css 中携带了 @import url(‘./body.css’),会导致报错,把这行注释掉就可以运行了。

bundle、bundleAsync

bundle 同步打包 css 及对应的依赖(@import 导入的文件);bundleAsync 异步打包 css 及对应的依赖(@import 导入的文件)。

async function transform() {let result = await lightningcss.bundleAsync({filename: "./index.css",// analyzeDependencies: true,});return result;
}transform().then((res) => {console.log(res);
});
// {
//  code: <Buffer 40 69 6d 70 6f 72 74 20 22 2e 2f 62 6f 64 79 2e 63 73 73 22 3b 0a 0a 61 2c 20 2e 6c 69 6e 6b 20 7b 0a 20 20 63 6f 6c 6f 72 3a 20 72 65 64 3b 0a 7d 0a ... 28 more bytes>,
//  map: null,
//  exports: null,
//  references: null,
//  dependencies: null,
//  warnings: []
// }

与 transform 方法返回的结果类似,不同的是 bundle、bundleAsync 会把 @import 导入的文件也输出在 code 字段中:

res.code.toString();
// body {
//   background: #9db158;
// }// a, .link {
//   color: red;
// }// a:hover {
//   color: #00f;
// }

此时即使添加了 analyzeDependencies: true 配置,也不会打印出任何依赖相关信息。

composeVisitors

将多个 visitor 对象合并成一个。

visitor 对象

自定义转换是通过将 visitor 对象传递给 lightningcss 来实现的。visitor 对象包含一个或多个函数,这些函数是针对特定值类型(如规则、属性或长度)调用的。一般来说,我们应该尽可能具体地说明要处理的值的类型。这样,lightningcss 需要尽可能少地调用JS,使用尽可能小的对象,从而提高性能。

async function transform() {let result = await lightningcss.transform({code: Buffer.from(`.foo {width: 12px;}`),visitor: {Length(length) {return {unit: length.unit,value: length.value * 2,};},},});return result;
}transform().then((res) => {console.log(res.code.toString());
});
// .foo {
//    width: 24px;
// }
let environmentVisitor = {EnvironmentVariable: {"--branding-padding": () => ({type: "length",value: {unit: "px",value: 20,},}),},
};let doubleFunctionVisitor = {FunctionExit: {double(f) {if (f.arguments[0].type === "length") {return {type: "length",value: {unit: f.arguments[0].value.unit,value: f.arguments[0].value.value * 2,},};}},},
};async function transform() {let result = await lightningcss.transform({code: Buffer.from(`.foo {padding: double(env(--branding-padding));}`),visitor: lightningcss.composeVisitors([environmentVisitor,doubleFunctionVisitor,]),});return result;
}transform().then((res) => {console.log(res.code.toString());
});
// .foo {
//    padding: 40px;
// }

browserslistToTargets

将一个浏览器列表转换成可以被 lightningcss 识别的目标。

通过使用 browserslist 结合一起使用:

lightningcss.browserslistToTargets(browserslist(">= 0.25%"))

在 target 字段中进行配置:

{filename: "./index.css",targets: lightningcss.browserslistToTargets(browserslist("IE 8")),
}
browserslist

browserslist 是一个轻量级但功能强大的工具,它为前端开发者提供了一种标准化的方法来选择需要支持的浏览器列表。这个项目旨在解决一个问题:在多如牛毛的浏览器版本中,如何决定我们的代码应该兼容哪些?它的存在使得我们可以通过简洁的语句定义我们的目标浏览器,从而自动化处理兼容性问题。

Browserslist 的核心是一个解析和处理查询字符串的引擎。开发者可以以 YAML、JSON 或直接在代码中定义支持的浏览器范围,例如 “last 2 versions” 或 “> 5%, not IE 11”。这些查询基于caniuse的数据,实时更新,确保了我们的项目始终与市场现状相符。

配置方式:

在工程中使用 Browserslist 有两种常见方式:在 package.json 相应字段中增加;独立的 browserslistrc 文件

在 package.json 中声明

"browserslist": ["> 1%","last 2 versions","not ie <= 8"
]

通过 browserslistrc 配置

# Browsers that we support
> 1%
last 2 versions
not ie <= 8

两种方式没有差异,大家根据自己习惯或者各自团队规范进行管理即可。

如何配置?

通过上述方式,我们可以圈定我们也支持哪些浏览器及版本,接下来就是如果通过 browserslist 进行配置?

可以通过 https://browsersl.ist/ 这个网站来查看,我们配置的内容具体支持的浏览器情况
可以选择在全球、某个地区或某个国家/地区拥有超过或低于一定规模观众的版本

  • 5% 全世界使用率大于5%
  • = 5% in US 美国使用率大于等于5%

选择最近的浏览器版本

  • last 2 versions 所有浏览器最新的2个版本
  • last 2 Chrome versions chrome 浏览器最新2个版本

特定浏览器版本

  • Chrome > 100 chrome 浏览器版本大于100
  • not Firefox ESR 排除 Firefox ESR

选择支持特定功能的浏览器版本

  • supports es6-module 支持 es6-module 的浏览器
  • supports css-grid 支持 css-grid 的浏览器

以上条件可以组合

  • 0.5%, last 2 versions 使用率大于0.5% 或者 所有浏览器最新2个版本(等价于 > 0.5% or last 2 versions)
  • 0.5% and last 2 versions 使用率大于0.5% 的浏览器最新2个版本
  • defaults 等价于 > 0.5%, last 2 versions, Firefox ESR, not dead

了解了上述配置语法,配置完成后,我们可以上述提到的 https://browsersl.ist/ 进行实时查看。除此,你也可以通过下述工具,来检测配置是否正确和支撑的具体浏览器版本。

配置

  • filename:在 transform、transformStyleAttribute 这两个 api 中是可选的,仅用于在错误或者 sourcemap 中提示文件名,而在 bundle、bundleAsync 中是必传的,以这个文件名作为入口文件进行处理。
  • code:在 transform、transformStyleAttribute 这两个 api 中是必传的,要进行处理的 css 内容,与其他css处理器不同的是,它只支持 Uint8Array 格式,传入 string 格式会报错,在 node 中可以使用 buffer.from(string) 进行转换后传递,在浏览器中使用 new TextEncoder().encode(string) 进行转换后传递,在 bundle、bundleAsync 中这个配置无效。
  • minify:可选,是否要压缩
  • target:可选,浏览器目标
  • analyzeDependencies:可选,是否要分析 url() 导入的依赖,默认 false,设置成true 的话返回的结果会携带相关依赖信息。在 bundle、bundleAsync 中无效,因为会被打包在一个文件中,不会有任何的 dependence。
  • errorRecovery:可选,默认 false,是否要忽略无效的规则或者声明而不是直接报错。设置成 true 的话不会无效的规则、声明,照样打包,但是会提供警告。
  • visitor:可选,可以用于自定义转换器或者分析 lightningcss 的转换结果。

与工具集成

在 deno 或者浏览器中直接使用

需要导入 lightningcss-wasm 才能使用,在浏览器中使用的话需要支持 WebAssembly 特性,同时因为 lightningcss 不支持使用 string 的格式传递要转换成 css 代码,需要使用 TextEncoder 进行转换后传递,最后使用 TextDecoder 对结果进行处理:

import init, { transform } from 'https://esm.run/lightningcss-wasm';await init();let {code, map} = transform({filename: 'style.css',code: new TextEncoder().encode('.foo { color: red }'),minify: true,
});console.log(new TextDecoder().decode(code));

bundle 及 composeVisitors 暂时不支持在浏览器中使用。

在 webpack 中使用

需要安装 lightningcss、css-minimizer-webpack-plugin、browserslist 这三个依赖,之后在 webpack.config.js 文件中进行配置:

// webpack.config.js
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const lightningcss = require('lightningcss');
const browserslist = require('browserslist');module.exports = {optimization: {minimize: true,minimizer: [new CssMinimizerPlugin({minify: CssMinimizerPlugin.lightningCssMinify,minimizerOptions: {targets: lightningcss.browserslistToTargets(browserslist('>= 0.25%'))},}),],},
};

在 vite 中使用

vite 是默认支持 lightningcss 的,但是也要先安装 lightningcss:

import {browserslistToTargets} from 'lightningcss';export default {css: {transformer: 'lightningcss',lightningcss: {targets: browserslistToTargets(browserslist('>= 0.25%'))}},build: {cssMinify: 'lightningcss'}
};

可配置字段可以查阅Lightning CSS 仓库

cli

lightningcss 提供了一个独立的 cli 工具,可以用于编译、压缩、打包 css 文件。它只针对于css的编译,如果我们需要代码分割或者支持其他类型的css文件这些更强大的功能,就不能使用这个 cli 工具了。

安装 cli:

npm install --save-dev lightningcss-cli
{"scripts": {"build": "lightningcss --minify --bundle --targets '>= 0.25%' input.css -o output.css"}
}

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

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

相关文章

k8s集群可视化工具安装(dashboard)

可视化安装 2.1、下载相关的yaml文件 wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0/aio/deploy/recommended.yaml Vim recommended.yaml 2.2、部署 kubectl apply -f recommended.yaml 查看那kubernetes-dashboard命令空间下的资源 kubectl get …

ZLMRTCClient配置说明与用法(含示例)

webRTC播放视频 后面在项目中会用到通过推拉播放视频流的技术&#xff0c;所以最近预研了一下webRTC 首先需要引入封装好的webRTC客户端的js文件ZLMRTCClient.js 下面是地址需要的自行下载 http://my.zsyou.top/2024/ZLMRTCClient.js 配置说明 new ZLMRTCClient.Endpoint…

技术分享!国产ARM + FPGA的SDIO通信开发介绍!

SDIO总线介绍 SDIO(Secure Digital lnput and Output),即安全数字输入输出接口。SDIO总线协议是由SD协议演化而来,它主要是对SD协议进行了一些扩展。 SDIO总线主要是为SDIO卡提供一个高速的I/O能力,并伴随着较低的功耗。SDIO总线不但支持SDIO卡,而且还兼容SD内存卡。支持…

韦东山嵌入式linux系列-具体单板的按键驱动程序(查询方式)

1 GPIO 操作回顾 &#xff08;1&#xff09;使能模块&#xff1b; &#xff08;2&#xff09;设置引脚的模式&#xff08;工作于GPIO模式&#xff09;&#xff1b; &#xff08;3&#xff09;设置GPIO本身&#xff08;输入/输出&#xff09;&#xff1b; &#xff08;4&…

在VMware创建Ubuntu24

目录 一、创建虚拟机 1. 自定义创建虚拟机 2. 设置虚拟机兼容 3. 选择镜像 4. 命名虚拟机&#xff0c;选择存放位置 5. 处理器配置 6. 内存配置 7. 网络类型配置 8. I/O控制器类型 9. 磁盘配置 10. 完成虚拟机创建 二、Ubuntu安装 1. 进入虚拟机中进行ubuntu的安…

浏览器打开PDF卡在加载(侧边翻译插件打不开PDF)

如果你的浏览器安装了一些翻译插件&#xff0c;那么可能会导致PDF加载不出来 比如我的浏览器中安装了“侧边翻译”&#xff0c;而我在view Elsever的论文时出现了加载不出来的问题—— 仍然以此扩展为例&#xff0c;那么解决办法是&#xff1a; 取消勾选——

Docker简单快速入门

1. 安装Docker 基于 Ubuntu 24.04 LTS 安装Docker 。 # 更新包索引并安装依赖包 sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common# 添加Docker的官方GPG密钥并存储在正确的位置 curl -fsSL https://mirror…

【屏显MCU】多媒体接口总结

本文主要介绍【屏显MCU】的基本概念&#xff0c;用于开发过程中的理解 以下是图层叠加示例 【屏显MCU】多媒体接口总结 0. 个人简介 && 授权须知1. 三大引擎1.1 【显示引擎】Display Engine1.1.1 【UI】 图层的概念1.1.2 【Video】 图层的概念1.1.3 图层的 Blending 的…

C++ 学习补充 1:短链算法

短链算法 短链算法&#xff1a; 将长链接 转化为 一个短key 之所以不是短url 是因为 &#xff0c;url 短链不区分大小写&#xff0c;可用空间比较小。 短链算法通常用于将一个长网址转换成一个较短的字符串&#xff0c;以便于分享和存储。这种算法通常需要满足以下条件&#…

数据结构(2)双向链表

链表 线性表的链式存储 解决顺序存储的缺点&#xff0c;插入和删除&#xff0c;动态存储问题。 特点&#xff1a; 线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素&#xff0c; 存储单元可以是连续的&#xff0c;也可以不连续。可以被存储…

nginx代理缓存配置-Linux(CentOS)

代理缓存 1. 编写主配置文件2. 编辑虚拟机配置文件3. 重启nginx服务 nginx代理服务配置&#xff0c;基于http协议 开启代理缓存的前提是已经开启了代理服务&#xff0c;请确保已经开启代理服务 1. 编写主配置文件 主配置文件通常在/etc/nginx/nginx.conf&#xff0c;在该文件…

【云原生】ReplicationController控制器详解

ReplicationController 文章目录 ReplicationController说明一、ReplicationControllere介绍二、ReplicationController如何工作三、运行一个ReplicationController四、编写一个ReplicationController清单注意事项4.1、Pod模板4.2、ReplicationController上的标签4.3、Pod选择算…

python机器学习8--自然语言处理(1)

1.基本定义&#xff1a; 语义&#xff1a;就是一句话的重点是什么。 自定词汇&#xff1a;因为语言、文字太多&#xff0c;自定和处理你所关心的重点词汇。 简体转繁体代码 from opencc import OpenCCtext1 "我去过清华大学" openCC OpenCC(s2t) line openCC.…

Typora 【最新1.8.6】版本安装下载教程 (轻量级 Markdown 编辑器),图文步骤详解,免费领取(软件可激活使用)

文章目录 软件介绍软件下载安装步骤激活步骤 软件介绍 Typora 是一款专为 Markdown 爱好者设计的文本编辑器&#xff0c;它结合了简洁的界面设计与强大的 Markdown 渲染能力&#xff0c;为用户提供了一个流畅、高效的写作环境。以下是对 Typora 更详细的介绍&#xff1a; 核心特…

vue使用mavonEditor(流程图、时序图、甘特图实现)

mavonEditor 安装mavonEditor $ npm install mavon-editor --save使用 // 全局注册import Vue from vueimport mavonEditor from mavon-editorimport mavon-editor/dist/css/index.css// useVue.use(mavonEditor)new Vue({el: #main,data() {return { value: }}})//局部使用…

js-vue中多个按钮状态选中类似于复选框与单选框实现

1.vue中多个按钮状态选中类似于复选框 在Vue中处理多个按钮的选中状态切换&#xff0c;通常我们会利用Vue的响应式数据系统来追踪每个按钮的选中状态。 html <div id"app"> <button v-for"button in buttons" :key"button.id" :c…

MATLAB绘制方波、锯齿波、三角波、正弦波和余弦波、

一、引言 MATLAB是一种具有很强的数值计算和数据可视化软件&#xff0c;提供了许多内置函数来简化数学运算和图形的快速生成。在MATLAB中&#xff0c;你可以使用多种方法来快速绘制正弦波、方波和三角波。以下是一些基本的示例&#xff0c;展示了如何使用MATLAB的命令来实现正弦…

数据科学统计面试问题 -40问

前 40 名数据科学统计面试问题 一、介绍 正如 Josh Wills 曾经说过的那样&#xff0c;“数据科学家是一个比任何程序员都更擅长统计、比任何统计学家都更擅长编程的人”。统计学是数据科学中处理数据及其分析的基本工具。它提供了工具和方法&#xff0c;可帮助数据科学家获得…

第五节shell脚本中的运行流程控制(5.2)

b)应答语句中的变量 #!/usr/bin/expect spawn sh ask.sh set timeout 5 set NAME [ lindex $argv 0 ] set AGE [ lindex $argv 1 ] set SUB [ lindex $argv 2 ] set FEEL [ lindex $argv 3 ] expect {"name" { send "$NAME\r";exp_continue }"old&qu…

【React】条件渲染:深入探讨高效开发技巧与最佳实践

文章目录 一、什么是条件渲染&#xff1f;二、条件渲染的实现方式三、条件渲染的最佳实践四、复杂条件渲染的实现 在现代前端开发中&#xff0c;React 已成为开发者构建用户界面的首选框架之一。React 的强大之处在于其组件化和状态管理能力&#xff0c;而条件渲染则是 React 开…