mcpField
M
migrate-nativewind-to-uniwind

migrate-nativewind-to-uniwind

github.com/hairyf開発2642 回インストール2 週間前に更新
リポジトリ

migrate-nativewind-to-uniwind について

React Native プロジェクトを NativeWind から Uniwind へ移行する手順を示すコーディングスキルです。Tailwind CSS 4 を前提に、設定、テーマ、コンポーネントのラップ、移行時の確認項目を扱います。

主な機能

  1. 01NativeWind 依存関係の削除
  2. 02Uniwind と Tailwind CSS 4 の設定
  3. 03Metro と CSS の設定更新
  4. 04テーマと型定義の移行
  5. 05相互運用と className の更新
  6. 06移行確認のガイド

活用シーン

  1. 01Expo アプリを NativeWind から移行
  2. 02テーマ値を JS から CSS へ移行
  3. 03cssInterop を withUniwind に置換
  4. 04移行時のスペーシング維持

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/hairyf/skills --skill migrate-nativewind-to-uniwind

インストール後、Claude Code で/migrate-nativewind-to-uniwindを入力して読み込まれたか確認します。

同梱ファイルLICENSE.mdSYNC.md

詳細

NativeWind から Uniwind への移行

Uniwind は NativeWind を置き換え、パフォーマンスと安定性を向上させます。Tailwind CSS 4 が必要で、JS 設定の代わりに CSS ベースのテーマ設定を使用します。

移行前のチェックリスト

作業を始める前に、既存の設定ファイルを確認して、現在の設定を把握してください。

  • package.json(NativeWind のバージョン、依存関係)
  • tailwind.config.js / tailwind.config.ts
  • metro.config.js
  • babel.config.js
  • global.css または同等の CSS エントリーファイル
  • nativewind-env.d.ts または nativewind.d.ts
  • nativewind の cssInterop または remapProps を使用しているファイル
  • react-native-css-interop からインポートしているファイル
  • NativeWind の ThemeProvider(vars() の使用)

ステップ 1:NativeWind と関連パッケージを削除する

以下のパッケージがインストールされている場合は、すべてアンインストールしてください。

npm uninstall nativewind react-native-css-interop
# or
yarn remove nativewind react-native-css-interop
# or
bun remove nativewind react-native-css-interop

重要:react-native-css-interop は NativeWind の依存パッケージであり、削除する必要があります。移行時に見落とされることがよくあります。コードベース全体を検索して、このパッケージからのインポートがないか確認してください。

rg "react-native-css-interop" -g "*.{ts,tsx,js,jsx}"

見つかったインポートと使用箇所をすべて削除してください。

ステップ 2:Uniwind と Tailwind 4 をインストールする

npm install uniwind tailwindcss@latest
# or
yarn add uniwind tailwindcss@latest
# or
bun add uniwind tailwindcss@latest

tailwindcss がバージョン 4 以降であることを確認してください。

ステップ 3:babel.config.js を更新する

NativeWind の Babel プリセットを削除してください。

// REMOVE this line from presets array:
// 'nativewind/babel'

Uniwind 用の Babel プリセットは必要ありません。

ステップ 4:metro.config.js を更新する

NativeWind の Metro 設定を Uniwind の設定に置き換えてください。withUniwindConfig は最外側のラッパーにする必要があります。

変更前(NativeWind):

const { withNativeWind } = require('nativewind/metro');
module.exports = withNativeWind(config, { input: './global.css' });

変更後(Uniwind):

const { getDefaultConfig } = require('expo/metro-config');
// For bare RN: const { getDefaultConfig } = require('@react-native/metro-config');
const { withUniwindConfig } = require('uniwind/metro');

const config = getDefaultConfig(__dirname);

module.exports = withUniwindConfig(config, {
  cssEntryFile: './global.css',
  polyfills: { rem: 14 },
});

cssEntryFile は、プロジェクトのルートからの相対パス文字列にする必要があります(例:./global.css または ./app/global.css)。 このオプションに絶対パスや path.resolve(...) / path.join(...) を使用しないでください。

// ❌ Broken
cssEntryFile: path.resolve(__dirname, 'app', 'global.css')

// ✅ Correct
cssEntryFile: './app/global.css'

移行後に間隔やサイズの差異が発生しないよう、NativeWind のデフォルトの rem 値に合わせて、常に polyfills.rem を 14 に設定してください。

light / dark 以外のカスタムテーマ(NativeWind の vars() やカスタム ThemeProvider で定義したテーマなど)を使用している場合は、extraThemes に登録してください。light や dark は自動的に追加されるため、含めないでください。

module.exports = withUniwindConfig(config, {
  cssEntryFile: './global.css',
  polyfills: { rem: 14 },
  extraThemes: ['ocean', 'sunset', 'premium'],
});

オプション:

  • cssEntryFile(必須):CSS エントリーファイルへの相対パス文字列(プロジェクトのルートからのパス)
  • polyfills.rem(移行時に必須):NativeWind の rem 基準値に合わせて 14 に設定します
  • extraThemes(プロジェクトにカスタムテーマがある場合は必須):カスタムテーマ名の配列。light / dark は含めないでください
  • dtsFile(任意):生成される TypeScript 型のパス。デフォルトは ./uniwind-types.d.ts です
  • debug(任意):開発時にサポートされていない CSS プロパティをログに出力します

ステップ 5:global.css を更新する

NativeWind の Tailwind 3 ディレクティブを、Tailwind 4 のインポートに置き換えてください。

変更前:

@tailwind base;
@tailwind components;
@tailwind utilities;

変更後:

@import 'tailwindcss';
@import 'uniwind';

ステップ 6:CSS エントリーのインポートを更新する

global.css がメインの App コンポーネント(例:App.tsx)でインポートされていることを確認してください。アプリを登録するルートの index.ts / index.js ではインポートしないでください。そこにインポートすると、ホットリロードが機能しなくなります。

ステップ 7:NativeWind の型定義を削除する

nativewind-env.d.ts または nativewind.d.ts を削除してください。Uniwind は dtsFile で指定したパスに独自の型を自動生成します。

ステップ 8:tailwind.config.js を削除する

tailwind.config.js / tailwind.config.ts を完全に削除してください。すべてのテーマ設定は、Tailwind 4 の @theme ディレクティブを使用して CSS に移行します。

カスタムテーマの値を global.css に移行してください。

変更前(tailwind.config.js):

module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#00a8ff',
        secondary: '#273c75',
      },
      fontFamily: {
        normal: ['Roboto-Regular'],
        bold: ['Roboto-Bold'],
      },
    },
  },
};

変更後(global.css):

@import 'tailwindcss';
@import 'uniwind';

@theme {
  --color-primary: #00a8ff;
  --color-secondary: #273c75;
  --font-normal: 'Roboto-Regular';
  --font-bold: 'Roboto-Bold';
}

フォントファミリーには単一のフォントを指定する必要があります。React Native はフォントのフォールバックに対応していません。

Step 9: cssInterop と remapProps の使用をすべて削除する

最も見落とされやすい手順です。 コードベース全体を検索してください:

rg "cssInterop|remapProps" -g "*.{ts,tsx,js,jsx}"

すべての cssInterop() / remapProps() 呼び出しを、Uniwind の withUniwind() に置き換えます:

変更前(NativeWind):

import { cssInterop } from 'react-native-css-interop';
import { Image } from 'expo-image';

cssInterop(Image, { className: 'style' });

変更後(Uniwind):

import { withUniwind } from 'uniwind';
import { Image as ExpoImage } from 'expo-image';

export const Image = withUniwind(ExpoImage);

withUniwind は className → style や、その他の一般的なプロパティを自動的にマッピングします。カスタムのプロパティマッピングを行う場合:

const StyledProgressBar = withUniwind(ProgressBar, {
  width: {
    fromClassName: 'widthClassName',
    styleProperty: 'width',
  },
});

ラップしたコンポーネントはモジュールレベル(レンダー関数内ではなく)で定義してください。各コンポーネントは一度だけラップします:

  • 1つのファイルだけで使用する場合 — ラップしたコンポーネントをそのファイル内で定義します:

    // screens/ProfileScreen.tsx
    import { withUniwind } from 'uniwind';
    import { BlurView as RNBlurView } from '@react-native-community/blur';
    
    const BlurView = withUniwind(RNBlurView);
    
    export function ProfileScreen() {
      return <BlurView className="flex-1" />;
    }
    
  • 複数のファイルで使用する場合 — 共有モジュールで一度だけラップして再エクスポートします:

    // components/styled.ts
    import { withUniwind } from 'uniwind';
    import { Image as ExpoImage } from 'expo-image';
    import { LinearGradient as RNLinearGradient } from 'expo-linear-gradient';
    
    export const Image = withUniwind(ExpoImage);
    export const LinearGradient = withUniwind(RNLinearGradient);
    

    その後、どこでも共有モジュールからインポートします:

    import { Image, LinearGradient } from '@/components/styled';
    

同じコンポーネントに対して、複数のファイルで withUniwind を呼び出さないでください。一度だけラップし、どこでもインポートします。

重要:react-native または react-native-reanimated のコンポーネントを withUniwind でラップしないでください。これらは標準で className をサポートしています。これには View、Text、Image、ScrollView、FlatList、Pressable、TextInput、Animated.View などが含まれます。withUniwind は、サードパーティ製コンポーネント(例:expo-image、expo-linear-gradient、@react-native-community/blur)にのみ使用してください。

重要 — スタイル以外の色プロパティには accent- プレフィックスを使用:React Native のコンポーネントには、style オブジェクトに含まれない color、tintColor、backgroundColor などのプロパティがあります。Tailwind クラスでこれらを設定するには、対応する *ClassName プロパティと accent- プレフィックスを使用します:

// color prop → colorClassName with accent- prefix
<ActivityIndicator
    className="m-4"
    size="large"
    colorClassName="accent-blue-500 dark:accent-blue-400"
/>

// color prop on Button
<Button
    colorClassName="accent-background"
    title="Press me"
/>

// tintColor prop → tintColorClassName with accent- prefix
<Image
    className="w-6 h-6"
    tintColorClassName="accent-red-500"
    source={icon}
/>

ルール:className は、スタイルベースのプロパティに対するすべての Tailwind ユーティリティを受け付けます。スタイル以外のプロパティ(color、tintColor など)には、accent- プレフィックスを付けた {propName}ClassName を使用します。これはすべての組み込み React Native コンポーネントに適用されます。

Step 10: NativeWind のテーマ変数を移行する

変更前(vars() を使用した NativeWind の JS テーマ):

import { vars } from 'nativewind';

export const themes = {
  light: vars({
    '--color-primary': '#00a8ff',
    '--color-typography': '#000',
  }),
  dark: vars({
    '--color-primary': '#273c75',
    '--color-typography': '#fff',
  }),
};

// In JSX:
<View style={themes[colorScheme]}>

変更後(Uniwind の CSS テーマ):

@layer theme {
  :root {
    @variant light {
      --color-primary: #00a8ff;
      --color-typography: #000;
    }
    @variant dark {
      --color-primary: #273c75;
      --color-typography: #fff;
    }
  }
}

重要:すべてのテーマバリアントで、まったく同じ CSS 変数のセットを定義する必要があります。light で --color-primary と --color-typography を定義する場合、dark(およびカスタムテーマ)でも両方を定義する必要があります。変数が一致しないと、Uniwind のランタイムエラーが発生します。

ThemeProvider のラッパーは不要です。JSX から NativeWind の <ThemeProvider> または vars() のラッパーを削除してください。React Navigation の <ThemeProvider> を使用している場合は、そのまま残します。

特定のサブツリーのテーマをプレビューまたは強制するために、プロジェクトでネストされたテーマラッパーを使用していた場合(たとえば、デモカード、設定のプレビュー、またはテーマの並列比較)、グローバルテーマを変更する代わりに、Uniwind Pro の ScopedTheme を使用します:

import { ScopedTheme } from 'uniwind';

<ScopedTheme theme="dark">
  <PreviewCard />
</ScopedTheme>

プロジェクトに light / dark 以外のカスタムテーマ(例:ocean、premium)がある場合は、次の手順が必要です:

  1. @variant を使用して CSS で定義します:
@layer theme {
  :root {
    @variant ocean {
      --color-primary: #0ea5e9;
      --color-background: #0c4a6e;
    }
  }
}
  1. extraThemes を使用して metro.config.js に登録します(light / dark は自動追加されるため不要です):
module.exports = withUniwindConfig(config, {
  cssEntryFile: './global.css',
  polyfills: { rem: 14 },
  extraThemes: ['ocean', 'premium'],
});

Step 11: セーフエリアユーティリティを移行する

NativeWind のセーフエリアクラスを Uniwind で使うには、明示的な設定が必要です:

import { SafeAreaProvider, SafeAreaListener } from 'react-native-safe-area-context';
import { Uniwind } from 'uniwind';

export default function App() {
  return (
    <SafeAreaProvider>
      <SafeAreaListener
        onChange={({ insets }) => {
          Uniwind.updateInsets(insets);
        }}
      >
        <View className="pt-safe px-safe">
          {/* content */}
        </View>
      </SafeAreaListener>
    </SafeAreaProvider>
  );
}

Step 12: rem 値を確認する

NativeWind は基準 rem 値として 14px を使用しますが、Uniwind のデフォルトは 16px です。手順 4 では、NativeWind のスペーシングを維持するために、metro 設定ですでに polyfills: { rem: 14 } を設定しています。ユーザーが Uniwind のデフォルト(16px)を明示的に希望する場合は、ポリフィルを削除できます。ただし、すべてのスペーシング/サイズが変わることを警告してください。

ステップ 13:className の重複を処理する

Uniwind は、競合する className を自動で重複排除しません(NativeWind は重複排除していました)。コードベースで className={`p-4 ${overrideClass}`} のような上書きパターンに依存している場合は、cn ユーティリティを設定してください。

まず、プロジェクトに cn ヘルパーがすでにあるか確認します(shadcn/ui プロジェクトでよく使われています):

rg "export function cn|export const cn" -g "*.{ts,tsx,js}"

存在する場合は、そのまま使用してください。ない場合は、依存関係をインストールして作成します:

npm install tailwind-merge clsx

lib/cn.ts を作成します(または、プロジェクトで utils を置いている場所に作成します):

import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';

export function cn(...inputs: ClassValue[]) {
    return twMerge(clsx(inputs));
}

使用方法:

import { cn } from '@/lib/cn';

<View className={cn('p-4 bg-white', props.className)} />
<Text className={cn('text-base', isActive && 'text-blue-500', disabled && 'opacity-50')} />

twMerge を直接使う代わりに cn を使用してください。重複排除の前に clsx で条件付きクラス、配列、falsy 値を処理します。

重要ユーティリティも Uniwind でサポートされています。移行した NativeWind のコードで Tailwind の important 修飾子を使って意図的に上書きしている場合は、そのまま残してください:

<View className="bg-blue-500 !bg-red-500" />
<Pressable className="bg-blue-500 active:!bg-red-500" />

重要ユーティリティは、同じスタイルプロパティの非重要ユーティリティを上書きします。インラインの style は、important な className ユーティリティよりも優先度が高く、常に最優先されます。

ステップ 14:アニメーション付きクラス名を更新する

プロジェクトで NativeWind の animated-* や transition クラスのパターンを使用していた場合は、明示的な react-native-reanimated の使用に移行してください。Uniwind OSS では、NativeWind スタイルのアニメーション付きクラスの動作は提供されません。

移行の基準として、こちらのガイドセクションを使用してください:

ステップ 15:残っている NativeWind の参照を削除する

最終確認として、残っている参照を検索して削除します:

rg "nativewind|NativeWind|native-wind" -g "*.{ts,tsx,js,jsx,json,css}"

以下を確認してください:

  • すべてのファイルにある NativeWind のインポート
  • package.json 内の nativewind(devDependencies も確認)
  • package.json 内の react-native-css-interop
  • babel.config.js 内の NativeWind Babel プリセット
  • metro.config.js 内の NativeWind Metro ラッパー
  • nativewind-env.d.ts または nativewind.d.ts ファイル
  • cssInterop() または remapProps() の呼び出し
  • nativewind からの vars() のインポート

Uniwind の API とパターン

useUniwind — テーマへのアクセス(変更時に再レンダリング)

ドキュメント:https://docs.uniwind.dev/api/use-uniwind

import { useUniwind } from 'uniwind';

const { theme, hasAdaptiveThemes } = useUniwind();
// theme: current theme name — "light", "dark", "system", or custom
// hasAdaptiveThemes: true if app follows system color scheme

用途:UI でのテーマ名の表示、テーマに応じた条件付きレンダリング、テーマ変更時の副作用。

Uniwind Static API — テーマへのアクセス(再レンダリングなし)

再レンダリングを発生させずにテーマ情報にアクセスします:

import { Uniwind } from 'uniwind';

Uniwind.currentTheme    // "light", "dark", "system", or custom
Uniwind.hasAdaptiveThemes // true if following system color scheme

用途:ログ記録、分析、レンダリング外での命令型ロジック。

useResolveClassNames — className を Style オブジェクトに変換

ドキュメント:https://docs.uniwind.dev/api/use-resolve-class-names

Tailwind クラスを React Native の Style オブジェクトに変換します。className をサポートせず、withUniwind でラップできないコンポーネント(react-navigation のテーマ設定など)を扱う場合に使用します:

import { useResolveClassNames } from 'uniwind';

const headerStyle = useResolveClassNames('bg-blue-500');
const cardStyle = useResolveClassNames('bg-white dark:bg-gray-900');

<Stack.Navigator
  screenOptions={{
    headerStyle: headerStyle,
    cardStyle: cardStyle,
  }}
/>
useCSSVariable — JS で CSS 変数にアクセス

ドキュメント:https://docs.uniwind.dev/api/use-css-variable

CSS 変数の値をプログラムから取得します。変数には -- を付け、global.css で定義された変数と一致させる必要があります:

import { useCSSVariable } from 'uniwind';

const primaryColor = useCSSVariable('--color-primary');
const spacing = useCSSVariable('--spacing-4');

用途:アニメーション、サードパーティライブラリの設定、デザイントークンを使った計算。

CSS Functions — カスタムユーティリティ

ドキュメント:https://docs.uniwind.dev/api/css-functions

hairlineWidth()、fontScale()、pixelRatio() など、デバイスに応じた CSS 関数を使ってカスタムユーティリティを定義します。これらはどこでも使用できます(カスタム CSS クラス、@utility など)が、@theme {} 内では使用できません(静的な値のみ受け付けます)。再利用可能な Tailwind スタイルのクラスを作成するには、@utility を使用します:

@utility w-hairline { width: hairlineWidth(); }
@utility h-hairline { height: hairlineWidth(); }
@utility border-hairline { border-width: hairlineWidth(); }
@utility text-scaled { font-size: fontScale(); }

次のように使用します:<View className="w-hairline h-hairline" />

プラットフォームセレクター

ドキュメント:https://docs.uniwind.dev/api/platform-select

ios:、android:、web:、native: のプレフィックスを使って、プラットフォームごとに条件付きでスタイルを適用します:

<View className="ios:bg-red-500 android:bg-blue-500 web:bg-green-500">
  <Text className="ios:text-white android:text-white web:text-black">
    Platform-specific styles
  </Text>
</View>
テーマの切り替え

ドキュメント:https://docs.uniwind.dev/theming/basics

デフォルトでは、Uniwind はシステムのカラースキームに従います(アダプティブテーマ)。プログラムからテーマを切り替えるには:

import { Uniwind } from 'uniwind';

Uniwind.setTheme('dark');     // force dark
Uniwind.setTheme('light');    // force light
Uniwind.setTheme('system');   // follow system (default)
Uniwind.setTheme('ocean');    // custom theme (must be in extraThemes)
ScopedTheme — サブツリーのみにテーマを適用

ドキュメント:https://docs.uniwind.dev/api/scoped-themes

アプリ全体のテーマを変更せず、UI の一部(コンポーネントのプレビュー、テーマを適用したセクション、ネストされたデモなど)のみに異なるテーマが必要な場合は、ScopedTheme を使用します。

import { ScopedTheme } from 'uniwind';

<View className="gap-3">
  <PreviewCard />

  <ScopedTheme theme="light">
    <PreviewCard />
  </ScopedTheme>

  <ScopedTheme theme="dark">
    <PreviewCard />
  </ScopedTheme>
</View>

重要な動作:

  • 最も近い ScopedTheme が優先されます(スコープのネストに対応しています)
  • useUniwind、useResolveClassNames、useCSSVariable などのフックは、最も近いスコープ付きテーマに基づいて解決します
  • スコープ内の withUniwind でラップされたサードパーティ製コンポーネントも、そのスコープのテーマ値に基づいて解決します
  • ScopedTheme ではカスタムテーマ名を使用できます(extraThemes で定義する必要があります)
テーマに基づいたスタイル — CSS 変数を優先する

ドキュメント:https://docs.uniwind.dev/theming/style-based-on-themes

明示的な dark:/light: バリアントより、CSS 変数ベースのクラスを使用してください。 たとえば、次の代わりに:

// Avoid this pattern
<View className="light:bg-white dark:bg-black" />

CSS 変数を定義して、直接使用します:

@layer theme {
  :root {
    @variant light { --color-background: #ffffff; }
    @variant dark { --color-background: #000000; }
  }
}
// Preferred — automatically adapts to theme
<View className="bg-background" />

こちらのほうがすっきりして保守しやすく、カスタムテーマにも自動的に対応します。

CSS 変数の実行時更新

ドキュメント:https://docs.uniwind.dev/theming/update-css-variables

ユーザー設定や API レスポンスなどに基づいて、テーマ変数を実行時に更新します。

import { Uniwind } from 'uniwind';

// Preconfigure theme based on user input or API response
Uniwind.updateCSSVariables('light', {
  '--color-primary': '#ff6600',
  '--color-background': '#1a1a2e',
});

このパターンは、ユーザーが選択するブランドカラーや API 駆動のテーマなど、アプリで実行時のテーマ設定が実際に必要な場合にのみ使用してください。

tailwind-variants を使ったバリアント

ドキュメント:https://docs.uniwind.dev/tailwind-basics#advanced-pattern-variants-and-compound-variants

コンポーネントのバリアントと複合バリアントには、tailwind-variants ライブラリを使用します。

import { tv } from 'tailwind-variants';

const button = tv({
  base: 'px-4 py-2 rounded-lg',
  variants: {
    color: {
      primary: 'bg-primary text-white',
      secondary: 'bg-secondary text-white',
    },
    size: {
      sm: 'text-sm',
      lg: 'text-lg px-6 py-3',
    },
  },
});

<Pressable className={button({ color: 'primary', size: 'lg' })} />
モノレポのサポート

ドキュメント:https://docs.uniwind.dev/monorepos

プロジェクトがモノレポの場合、global.css に @source ディレクティブを追加して、Tailwind が CSS エントリーファイルのディレクトリ外にあるパッケージもスキャンするようにします(そのディレクトリに Tailwind クラスを含むコンポーネントがある場合のみ)。

@import 'tailwindcss';
@import 'uniwind';
@source "../../packages/ui/src";
@source "../../packages/shared/src";
よくある質問

ドキュメント:https://docs.uniwind.dev/faq

カスタムフォント:Uniwind が className をマッピングするのは font-family のみです。フォントファイルは別途読み込む必要があります(app.json の expo-font プラグイン、または bare RN の react-native-asset を使用します)。@theme のフォントファミリー名は、拡張子を除いたファイル名と完全に一致させてください。プラットフォームごとに異なるフォントを設定するには @variant を使用します(@layer theme { :root { } } の中に記述する必要があります):

@layer theme {
  :root {
    @variant ios { --font-sans: 'SF Pro Text'; }
    @variant android { --font-sans: 'Roboto-Regular'; }
    @variant web { --font-sans: 'system-ui'; }
  }
}

データセレクター:プロパティに基づくスタイル設定には data-[prop=value]:utility を使用します。サポートされるのは等値チェックのみです:

<View data-state={isOpen ? 'open' : 'closed'} className="data-[state=open]:bg-muted/50" />

Expo Router の global.css の配置場所:プロジェクトのルートに配置し、ルートレイアウト(app/_layout.tsx)でインポートしてください。app/ に配置した場合、外部のコンポーネントには @source ディレクティブが必要です。Tailwind は global.css の配置場所からスキャンします。

CSS の変更時にアプリが完全にリロードされる:Metro はプロバイダーが多数あるファイルをホットリロードできません。修正するには、global.css のインポートをコンポーネントツリーのより深い場所(ナビゲーションルートやホーム画面など)に移動してください。

グラデーション:組み込みでサポートされているため、追加の依存関係は必要ありません。bg-gradient-to-r from-red-500 via-yellow-500 to-green-500 を使用してください。expo-linear-gradient では useCSSVariable を使って色を取得してください。グラデーションの props は配列のため、withUniwind は動作しません。

スタイルの優先順位:インラインの style は常に className より優先されます。静的なスタイルには className を使用し、インラインスタイルは本当に動的な値に限って使用してください。同じプロパティに両方を併用するのは避けてください。

シリアライズエラー(Failed to serialize javascript object):キャッシュをクリアしてください:watchman watch-del-all 2>/dev/null; rm -rf node_modules/.cache && npx expo start --clear。一般的な原因には、複雑な @theme 設定や CSS 変数の循環参照があります。

Metro の unstable_enablePackageExports との競合:一部のアプリ(crypto など)ではこの機能が無効にされており、Uniwind が動作しなくなることがあります。選択的リゾルバーを使用してください:

config.resolver.unstable_enablePackageExports = false;
config.resolver.resolveRequest = (context, moduleName, platform) => {
  if (['uniwind', 'culori'].some((prefix) => moduleName.startsWith(prefix))) {
    return context.resolveRequest({ ...context, unstable_enablePackageExports: true }, moduleName, platform);
  }
  return context.resolveRequest(context, moduleName, platform);
};

セーフエリアクラス:p-safe、pt-safe、pb-safe、px-safe、py-safe、m-safe、mt-safe などが使用できます。また、-or-{value}(最小間隔)と -offset-{value}(追加間隔)のバリアントもサポートしています。

Next.js:公式にはサポートされていません。Uniwind は Metro と Vite 向けです。コミュニティ製プラグイン:uniwind-plugin-next。Next.js では標準の Tailwind CSS を使用し、デザイントークンを共有してください。

Vite:v1.2.0 以降でサポートされています。@tailwindcss/vite と併せて uniwind/vite プラグインを使用してください。

UI キット:HeroUI Native、react-native-reusables、Gluestack 4.1+ は Uniwind と非常に相性が良いです

既知の問題と注意点

  1. data- 属性*:Uniwind は NativeWind と同様に、条件付きスタイル設定のための data-[prop=value]:utility 構文をサポートしています。
  2. アニメーションスタイル:NativeWind のアニメーションクラスは react-native-reanimated に直接移行してください。Uniwind Pro には Reanimated のサポートが組み込まれています。

検証

移行後、次の項目を確認してください:

  1. npx react-native start --reset-cache(Metro キャッシュをクリア)または Expo の場合は npx expo start -c を実行する
  2. iOS と Android のすべての画面が正しく表示される
  3. テーマの切り替え(ライト/ダーク)が動作する
  4. カスタムフォントが正しく読み込まれる
  5. セーフエリアのインセットが正しく適用される
  6. スタイルが見つからないことを示すコンソール警告がない
  7. nativewind または react-native-css-interop からのインポートが残っていない

重要:Uniwind の API を推測しないでください。Uniwind の API、フック、コンポーネント、設定オプションについて不明な点がある場合は、公式ドキュメントを参照して確認してください:https://docs.uniwind.dev/llms-full.txt

コメント