实现一个vue按需打包的css和scss和less的Vite插件--可自动按需打包vue文件中的style标签下已使用的样式

文章介绍了在Vue3项目中,当引入的CSS和SCSS文件过大时,如何使用vite-plugin-vue-purifycss插件进行按需打包,避免包体积过大。插件能自动处理Vue文件中style标签下已使用的样式,支持设置cssList按需打包全局样式文件。用户需安装autoprefixer、postcss、precss等依赖,并通过vite配置文件启用插件,实现冗余样式的剔除。

背景以及用法

在写vue3项目的时候(我的项目是vite+vue3),引入的css和scss和less文件过大,由于项目只用到里面部分的样式,而打包却把整个文件都打包进去,这就导致包体积过大,因此写了这么一个vite插件以作优化(新版本添加的规则:现已可以自动按需打包vue文件中的style标签下已使用的样式),现在已经发布至npm官网,具体用法如下:


Install:
首先必须先下载的依赖包:(vite-plugin-vue-purifycss引用了autoprefixer、postcss、precss这三个依赖包)
npm install autoprefixer -D
npm install postcss -D
npm install precss -D

下载vite-plugin-vue-purifycss的方式:
npm install vite-plugin-vue-purifycss -D
# or
yarn add  vite-plugin-vue-purifycss -D
# or
cnpm install vite-plugin-vue-purifycss -D
# or
pnpm install vite-plugin-vue-purifycss -D

Usage1:cssList需要输入按需打包的css和scss和less样式文件名的用法(现已可以自动按需打包vue文件中的
style标签下已使用的样式)
vite.config.ts/vite.config.js
import vitePluginPurifycss from "vite-plugin-vue-purifycss"
export default defineConfig({
  plugins: [
    vue(),
    vitePluginPurifycss({
      cssList: ["xxxxx.css","xxxxx.scss","xxxxx.less"....],
    }),
]})
main.js/main.ts
import "xxxxxxxxx.css";
或者
import "xxxxxxxxx.scss";
或者
import "xxxxxxxxx.less";

Usage2:cssList无需输入按需打包的css和scss和less样式文件名,只要自动按需打包vue文件中的style标签下已使用的样式的功能的用法
vite.config.ts/vite.config.js
import vitePluginPurifycss from "vite-plugin-vue-purifycss"
export default defineConfig({
  plugins: [
    vue(),
    vitePluginPurifycss(),
]})

1.现已可以自动按需打包vue文件中的style标签下已使用的样式(强烈提议每个vue文件的style标签添加scoped属性)

2.如果想按需打包全局引入的css和scss和less样式文件,cssList必须输入按需打包对应的css或scss或less样式文件名(前提是该样式文件必须在mian.js/main.ts已经引入,按需打包才会生效)

3.如果cssList无需输入按需打包的css和scss和less文件名,则使用插件无需填入参数亦可

4.默认扫描全局的vue文件

Vite Plugin API

一个 Vite 插件可以额外指定一个 enforce 属性(类似于 webpack 加载器)来调整它的应用顺序。enforce 的值可以是pre 或 post。解析后的插件将按照以下顺序排列:

  • Alias

  • 带有 enforce: 'pre' 的用户插件

  • Vite 核心插件

  • 没有 enforce 值的用户插件

  • Vite 构建用的插件

  • 带有 enforce: 'post' 的用户插件

  • Vite 后置构建插件(最小化,manifest,报告)

开发Vite核心插件必须知道插件运行顺序,因为我们现在要处理冗余的css样式,所以现在我们要在vite的打包产物中剔除些没用的css样式,也就是“带有 enforce: 'post' 的用户插件”(输出阶段)这一阶段执行。

编写vite插件思路

按需打包css和scss和less文件的思路:目前需要获取全局vue文件引用到的选择器,再将文件中用到的选择器和cssList中的选择器根据设定的规则进行对比,最后剔除没有用到的选择器,剩下的选择器就是有用到的,这就达到按需打包css和scss和less效果了。

新版本添加的规则:现已可以自动按需打包vue文件中的style标签下已使用的样式--总体思路也是跟按需打包css和scss和less文件的思路大致一样的,不一样的是,绝大多数情况下,开发者总会在vue文件下的style标签后面加上scoped标识,这是为了保证在该style标签下修改样式不会影响到全局,确保样式私有化。在有scoped标识情况下,编译的时候会加上[data-v-xxxx]的唯一标识(该标识是从钩子transform(code, id, opt)的code中的__scopeId的字段可获取),所以我会在每一个vue文件下用到的选择器后面加上相应的[data-v-xxxx]唯一标识,如果style标签下的样式和vue文件的选择器带有的[data-v-xxxx]唯一标识是一致的证明该样式是在该vue文件下的style标签下的样式,再将样式文件中用到的选择器和对应的style标签下的选择器根据设定的规则进行对比,剔除没有用到的选择器,则达到按需打包vue文件中的style标签下已使用的样式。

以上我们知道了总体思路,接下来就需要得知vite和Rollup的钩子,我们需要在相应的钩子里做正确的事。查看vite官网和网上众多资料得知,钩子transform和generateBundle是我们需要的:

transform:这个钩子是处于把文件源码转换成目标代码这一阶段。transform(code, id, opt)中的code是文件转化之后的代码(实际是string类型),id是文件路径,我们可以根据文件后缀名,获得整个项目的vue文件对应的样式选择器和样式文件的路径(css和scss和less文件)。

generateBundle:这个钩子是处于把处于构建输出这一阶段,这里输出的已经是bundle产物,我们的目标就是改造输出的产物,所以在这里操作最为合适。generateBundle(__,bundle)中就是输出的Bundle文件列表。详细步骤:

  1. 获取cssList里面所有选择器(前提是用户填写的cssList中的样式文件名是项目中含有的,这里我会做个筛选)

  2. 与从钩子transform获取所有vue文件中的样式选择器进行对比,对比出多余的css样式。

  3. 引入postcss插件先把对应的Bundle文件转化为AST语法树,用多余的css样式匹配AST语法树相应的节点,并remove,余下的则是有用的selector节点,最后把余下的AST语法树转化成我们需要的source,这就是vite-plugin-vue-purifycss这个插件大概思路

具体可以去npm官网查看vite-plugin-vue-purifycss插件源代码

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值