百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

用Rust写了一个css插件,sass从此再见了

myzbx 2025-01-16 20:14 57 浏览

引言

团队很多项目,无论是vite还是webpack,写样式时都用了sass + postcss,然而随着项目越来越重,打包耗时也越来越长,ts和js代码可以使用swc等rust工具来编译,替换后确实提速效果是比较明显的,然而css打包也是影响整体打包速度的重要因素,而找了半天没发现太好的适合我们场景的css打包工具,所以决定自己写一个。

分析需求

首先我们90%的项目都用了postcss,依赖于一些postcss的插件,社区的lightningcss相当优秀,但是没法作为postcss插件使用,所以需要自己封装。

其实已经有大佬基于lightningcss提供Node版本的封装了postcss-lightningcss插件,但是遗憾的是该插件只有核心的编译功能是使用官方提供的用Rust开发封装过后的lightningcss模块,其他写 postcss 插件的逻辑还是使用js实现的,甚至还引入了node模块 browserslist来处理浏览器范围字符串的转化逻辑,所以性能上还是打了一些折扣的。这就让强迫症的我很是难受,要搞就搞个完美点的嘛。

@gogors/postcss-lightningcss-rs

那么 @
gogors/postcss-lightningcss-rs 即是从头到脚完全用Rust实现的postcss插件,包括浏览器范围字符串的转化逻辑也是用的Rust模块,例如你可以写[">= .25%", "chrome 90"]来描述兼容性,插件内部去帮你在处理具体文件前进行转化,只转化一次,而不是处理每个文件时都去转化一次。并将能缓存的地方缓存,只取我们需要的功能,相比于基于全量的node版本的lightningcss去封装,纯Rust版本的无论是逻辑还是体积都更轻量,但是功能上却是完全一致的。

最重要的是,该插件支持处理嵌套css语法,意味着我们不再需要使用sass,尤其是你只依赖sass的嵌套语法的情况,就完全没有必要使用sass了。

使用原生css去写嵌套语法,使用postcss + @
gogors/postcss-lightningcss-rs 去编译压缩,可以完全抛弃sass,获得极致的打包速度提升,要知道使用sass本身编译为css也是有成本的。

个人认为原生 CSS 已经支持变量、嵌套规则和计算功能,结合postcss来处理兼容性问题以及模块化导入,在日常开发需求中已经足够,Sass 提供了更丰富的编程特性,包括混合(Mixins)、继承、函数、控制指令(如条件语句和循环)等,虽然很强大,但是使用这些功能的同时也引入了复杂性和维护成本,代码可读性也会明显下降,同时还增加了构建编译成本,得不偿失。

所以如果你只需要嵌套功能的话,从此以后可以抛弃sass了,再也不用处理sass环境问题带来的各种坑了。

想当初,我还因此专门写了一篇又报gyp ERR!为什么有那么多人被node-sass 坑过? 的文章,sass真是把不少人折磨够呛。

安装

yarn add -D @gogors/postcss-lightningcss-rs

使用方法

const postcss = require("postcss");
import { postcssLightningcssPlugin } from "@gogors/postcss-lightningcss-rs";

postcss([postcssLightningcssPlugin(/* pluginOptions */)]);

选项

import { postcssLightningcssPlugin, Features } from "@gogors/postcss-lightningcss-rs";

postcssLightningcss({
  // 启用压缩(默认:true)
  minify: true,

  // 标记未使用的符号,会在压缩时移除
  unusedSymbols: ['foo', 'fade-in', '--color'],

  // 使用 browserslist 查询来指定支持哪些浏览器,以及要编译哪些特性
  targets: [">= .25%", "chrome 90"],
    // 即使目标支持,始终编译简化颜色和 CSS 嵌套。
  include: Features.Colors | Features.Nesting,
  // 即使目标不支持,也不要添加任何供应商前缀。
  exclude: Features.VendorPrefixes

  // true 启用所有文件的 CSS 模块,默认:false
  cssModules: true,

  // 单独启用各种css草案语法
  drafts: {
    // 启用自定义媒体查询(默认:false)
    customMedia: false,
    // 启用深选择器组合器(默认:false) 启用解析 Vue/Angular >>> 和 /deep/ 选择器运算符。
    deepSelectorCombinator: false,
  },

  // 是否忽略无效的规则和声明,而不是报错。启用后,将返回警告,并将无效的规则或声明从输出代码中省略。
  errorRecovery: false,

  // 用 JavaScript 可以应用的类名替换用户操作伪类。
  pseudoClasses: PseudoClasses,

});

Feature flags

include 和 exclude 选项允许明确开启或关闭某些功能。这些选项会覆盖基于提供的浏览器目标设置的默认值。例如,你可能只想编译颜色,并使用其他工具处理自动前缀或其他功能。或者,你可能想使用 Lightning CSS 处理除供应商前缀之外的所有内容。

include 和 exclude 选项使用 Features 枚举进行配置,可以从 lightningcss 导入。可以将多个标志进行位或操作以打开或关闭。

import { postcssLightningcssPlugin, Features } from '@gogors/postcss-lightningcss-rs';

let { code } = postcssLightningcssPlugin({
  // ...
  targets: [">= .25%", "chrome 90"],
  include: Features.Colors | Features.Nesting,
  exclude: Features.VendorPrefixes
});

更多 features flags

unusedSymbols

如果知道某些类名、ID、 @keyframes 规则、CSS 变量或其他 CSS 标识符未使用,可以使用 unusedSymbols 选项来删除它们。

let { code } = postcssLightningcssPlugin({
  // ...
  minify: true,
  unusedSymbols: ['foo', 'fade-in', '--color']
});

使用此配置,以下 CSS:

:root {
  --color: red;
}

.foo {
  color: var(--color);
}

@keyframes fade-in {
  from { opacity: 0 }
  to { opacity: 1 }
}

.bar {
  color: green;
}

压缩为:

.bar{color:green}

Pseudo class replacement

Lightning CSS 支持用普通 CSS 类替换 CSS 伪类,如 :focus-visible ,这些类可以使用 JavaScript 操作。

let { code, map } = transform({
  // ...
  pseudoClasses: {
    focusVisible: 'focus-visible'
  }
});

以上配置将会替换所有选择器中的 :focus-visible 伪类为 .focus-visible 类。

以下伪类可以按照上述方式配置:

  • hover – 对应于 :hover 伪类
  • active – 对应于 :active 伪类
  • focus – 对应于 :focus 伪类
  • focusVisible – 对应于 :focus-visible 伪类
  • focusWithin – 对应于 :focus-within 伪类

CSS modules

启用 CSS 模块

postcssLightningcss({
  cssModules: true,
});

还可以将其与自定义命名模式结合使用:

postcssLightningcss({
  cssModules: {
    pattern: "my-company-[name]-[hash]-[local]",
  },
});

更多配置

使用该插件后可以移除的 PostCSS 插件

PostCSS 插件

lightningcss 选项

autoprefixer

取决于targets配置

postcss-clamp

取决于targets配置

postcss-color-hex-alpha

取决于targets配置

postcss-color-hsl

取决于targets配置

postcss-color-rgb

取决于targets配置

postcss-color-function

取决于targets配置

postcss-color-rebeccapurple

取决于targets配置

postcss-custom-media

options.drafts.customMedia

postcss-double-position-gradients

取决于targets配置

postcss-hwb-function

取决于targets配置

postcss-lab-function

取决于targets配置

postcss-logical

取决于targets配置

postcss-media-minmax

取决于targets配置

postcss-multi-value-display

取决于targets配置

postcss-nesting

取决于targets配置

postcss-normalize-display-values

取决于targets配置

postcss-oklab-function

取决于targets配置

postcss-overflow-shorthand

取决于targets配置

postcss-place

取决于targets配置

postcss-progressive-custom-properties

取决于targets配置

总结

使用纯血Rust版本的css编译压缩工具再加上去掉sass编译过程,打包速度简直起飞,小伙伴们快尝试起来。


原文链接:
https://juejin.cn/post/7452028372068728858

相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...