Vite 混淆 Tailwind 样式 class 类名

发布于 2024-07-02  105 次阅读


Post Stats

此文章有 2889 个字符, 大约要花 13 分钟阅读

背景

最近项目在使用tailwind时,发现样式表中存在很多个 w-full, h-full 类似的基础tw样式。

这些样式存在于不同的以umd形式引入的组件中。

因为我们的组件是远程加载,所以需要对tailwind的样式进行混淆。

混淆插件

插件使用的是 tailwindcss-patch + unplugin-tailwindcss-mangle/vite

官方文档0配置会取根目录下的.tw-patch\tw-class-list.json的tw类名记录。

并且会扫描目录下所有文件的tw类名。

但我们的每个组件只是开发时放在同一个项目下。运行时是独立的。所以魔改了一下配置。

整个vite构建会运行在 /components/${componentName}/

tailwindcss-patch

这个插件的功能是扫描代码,获取tw样式映射关系并导出。

使用该插件的 node api 获取(官方例子主要用cli command)。

import { TailwindcssPatcher } from 'tailwindcss-patch';
import componentConfig from './config.json';
import * as path from 'path';

const componentName = componentConfig.name;

const classPrefix = 'c' + Math.random().toString(36).substring(2, 4) + '-';

const twPatcher = new TailwindcssPatcher({
  patch: {
    basedir: `./components/${componentName}`,
  },
});

await twPatcher.extract({
  output: {
    filename: `./components/${componentName}/tw-class-list.json`,
    loose: true,
  },
  tailwindcss: {
    config: path.join(process.cwd(), `./components/${componentName}/tailwind.config.js`),
    cwd: path.join(process.cwd(), `./components/${componentName}`),
  },
});

/* ↓ vite defineConfig */

unplugin-tailwindcss-mangle/vite

这个插件是混淆替换插件,依赖于 tailwindcss-path 运行导出的tw样式映射关系。

import utwm from 'unplugin-tailwindcss-mangle/vite';
import componentConfig from './config.json';
import * as path from 'path';

// 组件名
const componentName = componentConfig.name;

export default defineConfig({
  plugins: [
    vue(),
    utwm({
      mangleClassFilter: (className) => {
        if (preserveClassNamesMap[className]) return false;
        return /[:-]/.test(className) || /^!/.test(className);
      },
      classListPath: path.join(process.cwd(), `./components/${componentName}/tw-class-list.json`),
      classGenerator: {
        customGenerate: () => {
          return classPrefix + Math.random().toString(36).substring(2, 8);
        },
      },
    }),
  ],
})

插件缺陷

这个插件的替换规则是全局替换,而不是基于语法树的替换。

所以官方屏蔽了不带-的样式替换。

如果不屏蔽的话,影响范围包括:

  • dom的属性会被替换,如svg的transform属性。
  • 变量名会被替换,如:visible static。
  • 行内样式/JS静态值会被替换。

可以通过增加前缀进行解决,但对已写了大量tw代码的项目不友好。