SuperAPI AI 工具集

expo-tailwind-setup

前端与建站

查看项目

更新于 10-16 13:59

技能介绍

用途

本技能面向在 Expo 应用中为 iOS、Android 与 Web 提供统一样式的场景,给出 Tailwind CSS v4 的完整搭建方式。它适用于使用 Expo Router 与 react-native-reanimated、并希望通过 className 直接书写样式的 React Native 项目。

主要能力与组成

该方案采用以下组件:

  • Tailwind CSS v4:现代 CSS-first 配置方式;
  • react-native-css:面向 React Native 的 CSS 运行时;
  • NativeWind v5:用于 React Native 中 Tailwind 的 Metro 转换器;
  • @tailwindcss/postcss:Tailwind v4 的 PostCSS 插件。 在 Expo 中不需要 autoprefixer(因为有 lightningcss),postcss 已由 expo 默认包含。

使用方式

安装

npx expo install tailwindcss@^4 nativewind@5.0.0-preview.2 react-native-css@0.0.0-nightly.5ce6396 @tailwindcss/postcss tailwind-merge clsx

并为 lightningcss 兼容性在 package.json 中加入 resolutions:

{
  "resolutions": {
    "lightningcss": "1.30.1"
  }
}

配置文件

创建或更新 metro.config.js:

const { getDefaultConfig } = require("expo/metro-config");
const { withNativewind } = require("nativewind/metro");

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

module.exports = withNativewind(config, {
  // inline variables break PlatformColor in CSS variables
  inlineVariables: false,
  // We add className support manually
  globalClassNamePolyfill: false,
});

创建 postcss.config.mjs:

export default {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};

创建 src/global.css:

@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css";

/* Platform-specific font families */
@media android {
  :root {
    --font-mono: monospace;
    --font-rounded: normal;
    --font-serif: serif;
    --font-sans: normal;
  }
}

@media ios {
  :root {
    --font-mono: ui-monospace;
    --font-serif: ui-serif;
    --font-sans: system-ui;
    --font-rounded: ui-rounded;
  }
}

不需要 Babel 配置

在 Tailwind v4 与 NativeWind v5 下,Tailwind 不再需要 babel.config.js。如果其中仅包含 NativeWind 配置,应删除它,不再需要如下内容:

// module.exports = function (api) {
//   api.cache(true);
//   return {
//     presets: [
//       ["babel-preset-expo", { jsxImportSource: "nativewind" }],
//       "nativewind/babel",
//     ],
//   };
// };

CSS 组件包装

由于 react-native-css 需要显式的 CSS 元素包装,需要创建可复用组件。主组件放在 src/tw/index.tsx,使用 useCssElement 与 useNativeVariable,并为 Link、View、Text、ScrollView、Pressable、TextInput、AnimatedScrollView、TouchableHighlight 提供包装;Image 组件放在 src/tw/image.tsx,将 objectFit、objectPosition 映射到 expo-image 的 contentFit、contentPosition;动画组件放在 src/tw/animated.tsx,导出 Animated.View。

使用示例

import { View, Text, ScrollView, Image } from "@/tw";

export default function MyScreen() {
  return (
    <ScrollView className="flex-1 bg-white">
      <View className="p-4 gap-4">
        <Text className="text-xl font-bold text-gray-900">Hello Tailwind!</Text>
        <Image
          className="w-full h-48 rounded-lg object-cover"
          source={{ uri: "https://example.com/image.jpg" }}
        />
      </View>
    </ScrollView>
  );
}

自定义主题变量

在 global.css 中使用 @theme 添加自定义主题变量,例如自定义字体、行高与 leading 尺度。也可以通过 @media ios 与 @media android 的平台媒体查询设置平台专属样式。

Apple 系统色与 CSS 变量

可创建 src/css/sf.css,用 light-dark() 定义强调色、灰阶、文本色与背景色,并在 @media ios 中使用 platformColor() 调用 iOS 原生颜色;随后在 @layer theme 的 @theme 中注册为 Tailwind 主题颜色(如 --color-sf-blue),即可在组件中使用 text-sf-text、bg-sf-bg 等类名。

在 JavaScript 中可通过 useCSSVariable 读取变量:

import { useCSSVariable } from "@/tw";

function MyComponent() {
  const blue = useCSSVariable("--sf-blue");

  return <View style={{ borderColor: blue }} />;
}

适用场景

适合需要跨 iOS、Android、Web 使用同一套 Tailwind 样式语言的 Expo 项目,尤其是希望以 CSS-first 方式配置主题、并需要平台专属字体与系统配色的应用。

与旧版本差异及限制

与 NativeWind v4 / Tailwind v3 的关键差异包括:不再使用 babel.config.js,配置为 CSS-first;使用 @tailwindcss/postcss 而非 tailwindcss;使用 @import "tailwindcss/..." 取代 @tailwind 指令;用 CSS 中的 @theme 取代 tailwind.config.js;组件必须用 useCssElement 包装才支持 className;Metro 配置使用 withNativewind 且需设置 inlineVariables: false。

排错提示:样式未生效时,确认应用入口已导入 CSS 文件、组件已用 useCssElement 包装、Metro 配置已应用 withNativewind;平台颜色不生效时,在 @media ios 中使用 platformColor(),并在 Web/Android 回退到 light-dark();TypeScript 报错时,需在组件 props 类型中加入 className。

安装命令使用 nativewind 5.0.0-preview.2 与 react-native-css 0.0.0-nightly 版本,属于预览与 nightly 依赖。除资料中给出的内容外,其他功能、收费、价格、平台支持与效果信息暂未提供。