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

背景以及用法

在写vue3项目的时候(我的项目是vite+vue3),引入的css和scss文件过大,由于项目只用到里面部分的样式,而打包却把整个文件都打包进去,这就导致包体积过大,因此写了这么一个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样式文件名的用法(现已可以自动按需打包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样式文件名,只要自动按需打包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样式文件名,则使用插件无需填入参数亦可

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

新版本添加的规则:现已可以自动按需打包vue文件中的style标签下已使用的样式--总体思路也是跟按需打包css或scss文件的思路大致一样的,不一样的是,绝大多数情况下,开发者总会在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文件)。

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-purifycs这个插件大概思路

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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Vite一个非常快速的前端构建工具,它内置了对 CSS 的支持,包括 CSS 模块化。下面是在 Vite 实现 CSS 模块化的步骤: 1. 安装依赖 首先,您要安装 `sass` 和 `sass-loader` 依赖项,它们将帮助您在 Vite 使用 CSS 模块化。 ``` npm install sass sass-loader --save-dev ``` 2. 配置 `vite.config.js` 在 `vite.config.js` ,您要配置 `css` 属性来启用 CSS 模块化和 `sass` 预处理器。例如: ``` import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], css: { modules: { localsConvention: 'camelCaseOnly' }, preprocessorOptions: { scss: { additionalData: `@import "@/styles/variables.scss";` } } } }) ``` 在上面的示例,`css.modules` 属性启用了 CSS 模块化,并将类名转换为 CamelCase 格式。`preprocessorOptions.scss` 属性启用了 `sass` 预处理器,并将全局变量文件导入到所有样式文件。 3. 创建样式文件 在您的样式文件,您可以使用 `:local()` 选择器来定义局部样式。例如: ``` .container { padding: 10px; background-color: white; border-radius: 5px; :local(.title) { font-size: 18px; color: #333; } :local(.description) { font-size: 14px; color: #666; } } ``` 在上面的示例,`:local()` 选择器定义了 `.title` 和 `.description` 类的局部样式。 4. 在组件使用样式 在您的组件,您可以像这样导入样式文件: ``` <template> <div class="container"> <h2 class="title">Title</h2> <p class="description">Description</p> </div> </template> <style module> @import "@/styles/your-styles.scss"; </style> ``` 在上面的示例,`<style module>` 标签启用了 CSS 模块化,并导入了样式文件。然后,您可以像这样在组件使用局部类名:`.title` 和 `.description`。 这就是在 Vite 实现 CSS 模块化的基本步骤。希望对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值