
关于
在 Expo 中使用 react-native-css 和 NativeWind v5 设置 Tailwind CSS v4,实现通用样式方案。
name: expo-tailwind-setup description: 在 Expo 中使用 react-native-css 和 NativeWind v5 设置 Tailwind CSS v4,实现跨平台统一样式 risk: unknown source: community version: 1.0.0 license: MIT
在 Expo 中使用 react-native-css 设置 Tailwind CSS
本指南介绍如何在 Expo 中使用 react-native-css 和 NativeWind v5 设置 Tailwind CSS v4,实现 iOS、Android 和 Web 的跨平台统一样式。
适用场景
- 需要在 Expo 应用中使用
react-native-css和 NativeWind v5 设置 Tailwind CSS v4 样式。 - 任务涉及为 Expo + Tailwind 配置 Metro、PostCSS、全局 CSS 或包版本。
- 希望在 Expo 项目中实现一套样式方案同时适配 iOS、Android 和 Web。
概述
本方案使用以下技术栈:
- Tailwind CSS v4 - 现代 CSS 优先配置
- react-native-css - React Native 的 CSS 运行时
- NativeWind v5 - 用于 React Native 的 Tailwind Metro 转换器
- @tailwindcss/postcss - Tailwind v4 的 PostCSS 插件
安装
# 安装依赖
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": {
"lightningcss": "1.30.1"
}
}
- Expo 中不需要 autoprefixer,因为已使用 lightningcss
- postcss 默认包含在 expo 中
配置文件
Metro 配置
创建或更新 metro.config.js:
// 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, {
// 内联变量会破坏 CSS 变量中的 PlatformColor
inlineVariables: false,
// 我们手动添加 className 支持
globalClassNamePolyfill: false,
});
PostCSS 配置
创建 postcss.config.mjs:
// postcss.config.mjs
export default {
plugins: {
"@tailwindcss/postcss": {},
},
};
全局 CSS
创建 src/global.css:
@import "tailwindcss/theme.css" layer(theme);
@import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css";
/* 平台特定字体族 */
@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 babel 预设,请将其移除:
// 如果 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)
import {
useCssElement,
useNativeVariable as useFunctionalVariable,
} from "react-native-css";
import { Link as RouterLink } from "expo-router";
import Animated from "react-native-reanimated";
import React from "react";
import {
View as RNView,
Text as RNText,
Pressable as RNPressable,
ScrollView as RNScrollView,
TouchableHighlight as RNTouchableHighlight,
TextInput as RNTextInput,
StyleSheet,
} from "react-native";
// 支持 CSS 的 Link 组件
export const Link = (
props: React.ComponentProps<typeof RouterLink> & { className?: string }
) => {
return useCssElement(RouterLink, props, { className: "style" });
};
Link.Trigger = RouterLink.Trigger;
Link.Menu = RouterLink.Menu;
Link.MenuAction = RouterLink.MenuAction;
Link.Preview = RouterLink.Preview;
// CSS 变量 hook
export const useCSSVariable =
process.env.EXPO_OS !== "web"
? useFunctionalVariable
: (variable: string) => `var(${variable})`;
// View 组件
export type ViewProps = React.ComponentProps<typeof RNView> & {
className?: string;
};
export const View = (props: ViewProps) => {
return useCssElement(RNView, props, { className: "style" });
};
View.displayName = "CSS(View)";
// Text 组件
export const Text = (
props: React.ComponentProps<typeof RNText> & { className?: string }
) => {
return useCssElement(RNText, props, { className: "style" });
};
Text.displayName = "CSS(Text)";
// ScrollView 组件
export const ScrollView = (
props: React.ComponentProps<typeof RNScrollView> & {
className?: string;
contentContainerClassName?: string;
}
) => {
return useCssElement(RNScrollView, props, {
className: "style",
contentContainerClassName: "contentContainerStyle",
});
};
ScrollView.displayName = "CSS(ScrollView)";
兼容工具
Claude CodeCursor
标签
移动端