发布于 2026-01-05 5 阅读
0

Tailwind + React:设置和设计模式

Tailwind + React:设置和设计模式

您可以在此处的模板中找到本文的所有源代码

如有任何疑问,欢迎随时在 Twitter 上联系我们。

Tailwind是什么?

你可能已经听说过 Tailwind 了,但如果你还没听说过,它本质上是一个实用性优先的 CSS 框架,与其他 CSS 框架(例如 Bootstrap 和 Foundation)相比,它的规范性要弱得多。根据tailwindcss.com 的描述,它是这样运作的:

一个高度可定制的底层 CSS 框架,为您提供构建定制设计所需的所有构建模块,而无需费力去覆盖任何烦人的、带有主观色彩的样式。

在我看来,这使得 Tailwind 成为项目开发的绝佳选择。它既能带来快速开发的优势,又避免了那些最终会被你覆盖的、过于死板的样式表。

那么,如果我们想在 React 中使用 Tailwind 呢?是不是只要引入一个样式表就行了?并非如此。由于 Tailwind 的构建方式以及它所采用的一些优化(例如清除未使用的 CSS),在 React 项目中正确配置它还需要一些额外的步骤。

项目设置

要开始使用 React,您可以直接进入自己的 React 项目,或者创建一个新的 React 项目npx create-react-app tailwind-react-app

安装依赖项

接下来,我们通过以下方式安装一些依赖项npm i @fullhuman/postcss-purgecss postcss-cli tailwindcss --save-dev

简要说明各项依赖关系:

  • fullhuman/postcss-purgecss用于清除未使用的 CSS,以创建尽可能小的最终 CSS 文件。如果不清除未使用的 CSS,Tailwind 未压缩后的文件大小实际上超过 2MB。
  • postcss-cliTailwind 是一个 PostCSS 插件。你不一定需要使用 PostCSS 作为预处理器,但为了简单起见,我们这里会使用它。
  • tailwindcss- Tailwind 库和实用程序

创建配置文件

现在我们已经安装好了依赖项,接下来需要创建几个配置文件。

首先,在项目根目录下运行命令创建 Tailwind 配置npx tailwind init。您可以根据需要在此处更新一些 Tailwind 配置。

接下来,创建 PostCSS 配置,方法是postcss.config.js在项目根目录下创建一个文件,并添加以下内容:

const purgecss = require('@fullhuman/postcss-purgecss')({
  content: ['./src/**/*.js', './src/**/*.jsx', './public/**/*.html'],
  defaultExtractor: (content) => content.match(/[A-Za-z0-9-_:/]+/g) || [],
});

module.exports = {
  plugins: [
    require('tailwindcss'),
    ...(process.env.NODE_ENV === 'production' ? [purgecss] : []),
  ],
};
Enter fullscreen mode Exit fullscreen mode

第一部分,我们需要进行一些必要的设置purgecss。这需要两部分内容。第一部分是可清除文件列表,包括 js、jsx 和 html 文件(您也可以添加.ts.tsx)。HTML 文件是必需的,这样可以避免基础样式(例如bodyhtml等)被清除。

第二部分用于定义提取器函数(即要保留的内容规则)。PurgeCSS 本质上比较简单,这意味着它会在上述文件类型中查找与正则表达式匹配的内容。了解这一点很重要,我们将在下文讨论模式时再次提及。

导入 Tailwind CSS

现在我们已经安装了依赖项并配置好了配置文件,接下来就可以将 Tailwind CSS 文件添加到我们的应用程序中了。首先,tailwind.csssrc/文件夹中创建一个文件,并添加以下 Tailwind 指令:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

这样,在构建 Tailwind 输出时,它会自动导入并编译样式。另外需要注意的是,我们可以在这个文件中添加自己的 Tailwind 自定义工具。有关添加新工具的更多信息,请点击此处

最后,让我们将输出文件(我们将在下一节中通过构建脚本创建)导入到我们的应用程序中app.js,以便它在整个应用程序中全局可用。

import './tailwind.output.css';
Enter fullscreen mode Exit fullscreen mode

app.js如果你的文件不在文件夹的根目录下,你可能需要更改路径/src,因为默认情况下它会输出到根目录。

设置构建脚本

要让 Tailwind 正常运行,最后一步是创建几个简单的构建脚本,以确保输出文件能够被成功构建。让我们将以下内容添加到脚本部分package.json

"tailwind:build": "NODE_ENV=production postcss src/tailwind.css -o src/tailwind.output.css",
"tailwind:dev": "postcss src/tailwind.css -o src/tailwind.output.css",
"prestart": "npm run tailwind:dev",
"prebuild": "npm run tailwind:build",
Enter fullscreen mode Exit fullscreen mode

我们创建了两个独立的 Tailwind 脚本。第:build一个用于生产环境构建(即运行PurgeCSS我们上面定义的脚本),而第二个用于开发环境构建,它保留了完整的 Tailwind CSS,因为我们需要在开发过程中访问所有样式。

接下来,prestart我们需要在启动 React 开发服务器之前运行开发版本。你还可以更进一步,添加一个监视脚本来检查 `.js` 文件是否发生更改tailwind.css,但我发现这个文件的添加/更改非常少见,所以如果出现这种情况,我通常直接重启开发服务器。

最后,最后一部分是prebuild运行生产(已清除)Tailwind 构建的脚本,这将生成一个仅包含我们在应用程序中实际使用的样式的 CSS 文件。

好了!现在你的 React 应用应该已经可以正常运行 Tailwind 了。如果你想更进一步,下一节我将介绍一些设计模式以及在 React 中使用 Tailwind 时常见的陷阱。

设计模式

现在我们的应用程序已经运行了 Tailwind,接下来我们可以讨论一些设计模式,这些模式使得在 React 组件中使用它变得容易。

不该做的事

在深入探讨一些模式之前,我认为有必要先提一下哪些事情不应该做。如何在你的应用中使用 Tailwind 最终取决于你的个人偏好,但有一个常见的错误会很快给你带来麻烦,那就是清除未使用的 CSS,正如我上面提到的。

我们来看一个例子来说明这个问题。假设我们有一个基本输入组件,如下所示:

<input className="border-2 border-gray-300 p-2" type="text" />
Enter fullscreen mode Exit fullscreen mode

现在,假设我们想在出现错误时有条件地将边框更改为红色。如果我们有一个error状态/属性变量,我们可能会想这样做:

<input
  className={`border-2 border-${error ? 'red-500' : 'gray-300'} p-2`}
  type="text"
/>
Enter fullscreen mode Exit fullscreen mode

乍一看,这似乎是正确的。事实上,它确实会渲染正确的类,并且在开发环境中运行良好。然而,一旦你构建了应用程序的生产版本,你会发现这些样式丢失了,这是为什么呢?正如前面提到的,PurgeCSS 会针对我们的生产版本运行,以创建尽可能小的 Tailwind CSS 文件。它会检查你提供的文件类型,并尝试查找与正则表达式匹配的内容。在这种情况下,当它检查这个组件文件时,由于 `<style>`border-red-500border-gray-300`<style>` 是动态生成的,因此不会匹配到它们。相反,它会遇到 `<style>`red-500和`<style>`,gray-300而这些样式无法按预期工作。

那么我们该如何避免这种情况呢?最简单的方法是,在代码中编写 Tailwind 类时,始终确保使用完整的类名,而不是动态生成的类名。因此,以上述示例为例,我们可以得到:

<input
  className={`border-2 ${error ? 'border-red-500' : 'border-gray-300'} p-2`}
  type="text"
/>
Enter fullscreen mode Exit fullscreen mode

现在当 PurgeCSS 对此文件运行时,它会保留border-red-500border-gray-300,正如它应该做的那样。

既然我们已经知道了哪些事情不应该做,那么让我们来看看一些我们可以在应用程序中使用的基本 Tailwind 模式。

基本模式

我最近一直在使用一种模式,即在组件上方定义所有类,并将每个元素定义在一个字符串对象中。

例如,以下是一个基本组件:

基本组件

按照上述模式,组件代码如下所示:

const classes = {
  wrapper: 'border-2 m-16 p-16',
  title: 'text-gray-800 text-xl text-center font-bold',
};

const BasicComponent = () => {
  return (
    <div className={classes.wrapper}>
      <h1 className={classes.title}>Basic Component</h1>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

这种基本模式有几个不错的优点:

  1. 它能保持组件定义的简洁性,尤其是在元素数量较多或类名较长的情况下。
  2. 这样可以轻松地在多个地方复用类。此外,如果需要更改样式,只需在组件中的一个地方进行修改即可。
  3. 所有类都在文件中完全定义,因此 PurgeCSS 没有问题。
  4. 您可以在一个简洁明了的地方查看组件的所有样式。

也就是说,当我们的应用需要使用更高级的组件,并且这些组件需要随着状态或属性的变化而变化时,我们该怎么办?让我们来看一个更高级的模式,它扩展了这种模式。

高级模式

现在我们已经有了在组件上方定义所有类的基本模式,当我们开始拥有更多动态组件时,我们可以更进一步。

例如,以下是一个更具动态性的组件:

动态组件

在上面的截图中,点击按钮时,按钮和副标题文本都会发生变化。我们来看一下这个组件的代码:

const classes = {
  wrapper: 'border-2 m-16 p-16 text-center',
  title: 'text-gray-800 text-xl font-bold',
  description: (active) =>
    `my-6 ${active ? 'text-red-900 font-medium' : 'text-gray-800'}`,
  button: 'py-2 px-4 bg-gray-100 border-2 focus:outline-none',
  buttonActive: 'bg-gray-400',
};

const AdvancedComponent = () => {
  const [active, setActive] = useState(false);

  return (
    <div className={classes.wrapper}>
      <h1 className={classes.title}>Advanced Component</h1>
      <p className={classes.description(active)}>
        I change based on the button click state.
      </p>
      <button
        className={clsx([classes.button, active && classes.buttonActive])}
        onClick={() => setActive((prevState) => !prevState)}
      >
        Click Me
      </button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

首先要注意的是description类。与其他类不同,它是一个函数,接受一个或多个参数,并输出一个略有不同的类名字符串(在本例中为文本颜色和字体粗细)。这样既保留了基本设计模式的优点,又增加了条件判断的属性。另外需要注意的是,这些类仍然完全定义,因此 PurgeCSS 不会出现任何问题。

另一种在保持基本模式的同时创建动态类的方法是使用 `<class>` 和 ` button<class> buttonActive` 类。在这种情况下,clsx模块用于根据条件动态添加类。` classes.button<class>` 类在没有条件的情况下添加(基础样式),而 ` <class>` 类classes.buttonActive仅在 `<class>` 为active真时添加。当您有多个条件性添加的类要添加到元素,或者您的类变得有点混乱,想要对其进行一些拆分时,这种方法也非常有效。同样,由于底层类是完全定义的,因此 PurgeCSS 可以很好地与此方法配合使用。

结论

我希望这篇文章能帮助你快速上手 React 应用中的 Tailwind,并给你一些启发,让你了解如何在组件中更轻松地使用它。

如果您有任何疑问、建议或遇到任何问题,欢迎随时在 Twitter 上联系我们

文章来源:https://dev.to/rfitz/tailwind-react-setup-and-design-patterns-f7o