likes
comments
collection
share

Tailwindcss 生产构建优化

作者站长头像
站长
· 阅读数 6

生产构建优化

在 Tailwindcss 里面包含了大量的原子类,但是在实际开发中,我们并不是说所有的原子类都会用到,因此在最终构建 css 的时候我们应该将没有使用到的原子类进行删除操作,从而优化我们的构建产物。

tree shaking

这里在 tailwindcss 里面要进行 tree shaking 操作,会用到 purgecss 插件,该插件实际上就是做 css 版本的 tree shaking,会将没有使用到的样式类进行一个删除。tailwindcss 里面是内置了 purgecss 插件的,原因很简单,tailwindcss 是一定需要做 tree shkaing 的,因为tailwindcss 里面有大量的原子类。

tailwindcss 是从 v1.4 版本开始内置 purgecss 的,最初的时候需要在配置文件里面配置一个名为 purge 的配置项:

// tailwind.config.js
module.exports = {
  purge: {
    content: ['./src/**/*.html', './src/**/*.js', './src/**/*.jsx', './src/**/*.ts', './src/**/*.tsx', './src/**/*.vue'],
    options: {
      safelist: ['bg-red-500', /^text-/],
    },
  },
  // ...
}

从 tailwindcss v2.0 开始,移除了 purge 配置项,直接在根配置项目下面配置 content 以及 safelist 即可:

module.exports = {
  content: [
    // 项目中需要扫描并移除未使用样式的文件路径
    './src/**/*.html',
    './src/**/*.vue',
    './src/**/*.jsx',
    // ...
  ],
  safelist: [
    'bg-red-500',
    'text-3xl',
    'lg:text-4xl',
  ]
}

接下来我们来看一个实际的例子:

 <body class="bg-gray-100">
    <div class="flex items-center justify-center min-h-screen">
      <button
        class="bg-blue-400 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded"
      >
        Click Me
      </button>
    </div>
  </body>

配置文件如下:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{html,js}"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

之后在生成的 output.css 文件中,我们可以看到生成的文件已经做了 tree shaking 操作,只包含上面 html 文件中使用到了的原子类。

如果要保留某个原子类,直接在 safelist 里面来做配置

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{html,js}"
  ],
  safelist: [
    "absolute"
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

限制变体的生成

tailwindcss 为了支持元素能够设置不同状态的原子类,所以推出了变体的功能,常见的变体:hover、focus、checked... 我们可以在这些变体后面添加原子类,表示该元素处于该变体状态时应用其原子类:

<button
  class="bg-blue-400 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded"
>
  Click Me
</button>

但是这里会涉及到一个问题,变体和原子类之间是可以产生数量非常巨大的组合的。例如 hover 变体可以和所有的原子类组合在一起,focus 变体也可以和所有的原子类组合在一起,在早期的时候,我们可以限制变体的生成,只需要在配置文件里面的 variants 配置项中进行一定的配置即可:

module.exports = {
  // ...
  variants: {
    backgroundColor: ['hover', 'focus'],
    textColor: ['hover', 'focus'],
  },
  // ...
}

在上面的配置中,我们就限制了变体的生成,仅仅只会对 backgroundColor 和 textColor 这两个原子类生成对应的 hover 以及 focus 变体,对生成的 CSS 文件进行了一个优化。

从 tailwindcss v2.0 开始,变体默认就是按需生成的,也就是说现在不需要在配置文件中进行变体的配置了,当然这个要不要配置最终取决于你使用的 tailwind 的版本。

使用 Postcss 进行后处理

tailwindcss 本身就是基于 postcss 进行构建的,因此可以和其他的 postcss 插件一起使用,进一步的优化生成构建。

下面是一个使用 postcss 插件的具体实例:

假设我们使用 cssnano 来对最终生成的 CSS 做一个压缩的处理,另外我们在生成最终的 CSS 的时候需要使用到 postcss 为我们提供的命令行里面的命令,所以还需要安装 postcss-cli

pnpm add cssnano postcss-cli -D

接下来需要在项目的根目录下面创建一个 postcss 的配置文件,书写如下的配置:

const tailwindcss = require("tailwindcss");
const cssnano = require("cssnano");

module.exports = {
  plugins: [
    tailwindcss,
    cssnano({
      preset: "default",
    }),
  ].filter(Boolean),
};

在上面的配置中,filter(Boolean) 表示过滤数组里面的假值,例如:

const isProduction = false;
const plugins = [
  'plugin1',
  'plugin2',
  isProduction && 'plugin3',
  isProduction && 'plugin4',
];

console.log(plugins);
// 输出:['plugin1', 'plugin2', false, false]

const filteredPlugins = plugins.filter(Boolean);

console.log(filteredPlugins);
// 输出:['plugin1', 'plugin2']

这样可以确保数组中使用到的都是真实的插件,false 值被移除掉。

最后一步,就是在 package.json 里面添加新的命令脚本:

"build": "postcss ./src/styles.css -o ./dist/output.css --watch"