实现一个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 + Vue3 + TypeScript + Pinia + Vue Router + Axios + SCSS自动导入 API 的设置,你可以按照以下步骤进行操作: 1. 首先,确保你已经安装了 Node.js,并且版本大于等于 12.0.0。 2. 创建一个新的 Vue 项目,可以使用 Vue CLI 或者手动创建一个文件夹。 3. 在项目根目录下,打开终端并执行以下命令安装 Vite: ```bash npm init vite@latest ``` 按照提示选择你的项目配置,包括选择 Vue 3、TypeScript 和其他选项。 4. 进入项目目录并安装依赖: ```bash cd your-project-name npm install ``` 5. 安装 Pinia 插件: ```bash npm install pinia ``` 6. 创建一个 `src/store` 目录,并在其创建 `index.ts` 文件,用于定义和导出你的 Pinia store。 ```typescript // src/store/index.ts import { createPinia } from 'pinia' export const store = createPinia() // 可以在这里定义你的 store 模块 ``` 7. 在项目根目录下创建 `src/api` 目录,用于存放 API 请求相关的文件。 8. 在 `src/api` 目录下创建一个 `index.ts` 文件,用于自动导入所有 API 文件。 ```typescript // src/api/index.ts const modules = import.meta.globEager('./*.ts') const apis: any = {} for (const path in modules) { if (path !== './index.ts') { const moduleName = path.replace(/^.\/|\.ts$/g, '') apis[moduleName] = modules[path].default } } export default apis ``` 这样,你就可以在 `src/api` 目录下创建各种 API 请求的文件,例如 `user.ts`: ```typescript // src/api/user.ts import axios from 'axios' export function getUser(id: number) { return axios.get(`/api/user/${id}`) } ``` 然后,在你的组件使用自动导入的 API: ```typescript import { defineComponent, ref } from 'vue' import { useUserStore } from '@/store' import apis from '@/api' export default defineComponent({ setup() { const userStore = useUserStore() const userId = ref(1) const fetchUser = async () => { const response = await apis.user.getUser(userId.value) userStore.setUser(response.data) } return { userId, fetchUser, } }, }) ``` 以上就是使用 Vite + Vue3 + TypeScript + Pinia + Vue Router + Axios + SCSS自动导入 API 的基本设置。你可以根据自己的求进一步配置和扩展。希望对你有所帮助!
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值