Skip to content

Vite plugin doesn't work with Storybook 9 #259

Description

@a16n-dev

What happened?

When attempting to use the Vite plugin in a Storybook 9 project, I get the following error:

TypeError [ERR_INVALID_ARG_TYPE]: The "paths[0]" argument must be of type string. Received undefined
 at Object.resolve (node:path:1222:7)                                                                                                          
    at Object.<anonymous> (/node_modules/uniwind/dist/vite/index.cjs:14:37)

It seems the culprit is this snippet in the vite plugin:

const componentPath = path.resolve(
import.meta.dirname,
'../module/components/web/index.js',
)

which then compiles to the following in dist/vite/index.cjs:

const componentPath = path__default.resolve(
  undefined,
  "../module/components/web/index.js"
);

We're working around the issue for now by patching in __dirname:

const componentPath = path__default.resolve(
-  undefined,
+  __dirname,
   "../module/components/web/index.js"
 );

This issue also doesn't seem to be present in Storybook 10 and above

Project setup:

storybook/main.ts
import type { StorybookConfig } from '@storybook/react-native-web-vite';
import tailwindcss from '@tailwindcss/vite';
import { uniwind } from 'uniwind/vite';

const config: StorybookConfig = {
  "stories": [
    "../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)"
  ],
  "addons": [],
  "framework": "@storybook/react-native-web-vite",
  viteFinal: async (config) => {
    config.plugins = [
      ...(config.plugins || []),
      tailwindcss(),
      uniwind({
        cssEntryFile: '../global.css',
      }),
    ];

    return config;
  },
};
export default config;
package.json
{
  "name": "uniwind-storybook",
  "main": "expo-router/entry",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start",
    "reset-project": "node ./scripts/reset-project.js",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "lint": "expo lint",
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },
  "dependencies": {
    "@expo/vector-icons": "^15.0.3",
    "@react-navigation/bottom-tabs": "^7.4.0",
    "@react-navigation/elements": "^2.6.3",
    "@react-navigation/native": "^7.1.8",
    "@tailwindcss/vite": "^4.1.18",
    "expo": "~54.0.30",
    "expo-constants": "~18.0.12",
    "expo-font": "~14.0.10",
    "expo-haptics": "~15.0.8",
    "expo-image": "~3.0.11",
    "expo-linking": "~8.0.11",
    "expo-router": "~6.0.21",
    "expo-splash-screen": "~31.0.13",
    "expo-status-bar": "~3.0.9",
    "expo-symbols": "~1.0.8",
    "expo-system-ui": "~6.0.9",
    "expo-web-browser": "~15.0.10",
    "react": "19.1.0",
    "react-dom": "19.1.0",
    "react-native": "0.81.5",
    "react-native-gesture-handler": "~2.28.0",
    "react-native-reanimated": "~4.1.1",
    "react-native-safe-area-context": "~5.6.0",
    "react-native-screens": "~4.16.0",
    "react-native-web": "~0.21.0",
    "react-native-worklets": "0.5.1",
    "tailwindcss": "^4.1.18",
    "uniwind": "^1.2.2"
  },
  "devDependencies": {
    "@storybook/react-native-web-vite": "^9.1.10",
    "@types/react": "~19.1.0",
    "eslint": "^9.25.0",
    "eslint-config-expo": "~10.0.0",
    "eslint-plugin-storybook": "^9.1.10",
    "storybook": "^9.1.10",
    "typescript": "~5.9.2",
    "vite": "7.3.0"
  },
  "private": true,
  "packageManager": "pnpm@9.15.4+sha512.b2dc20e2fc72b3e18848459b37359a32064663e5627a51e4c74b2c29dd8e8e0491483c3abb40789cfd578bf362fb6ba8261b05f0387d76792ed6e23ea3b1b6a0"
}
tsconfig.json
{
  "compilerOptions": {
    "allowJs": true,
    "esModuleInterop": true,
    "jsx": "react-native",
    "lib": ["DOM", "ESNext"],
    "module": "preserve",
    "moduleDetection": "force",
    "moduleResolution": "bundler",
    "customConditions": ["react-native"],
    "noEmit": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "target": "ESNext",
    "strict": true,
    "paths": {
      "@/*": ["./*"],
    }
  },
  "include": [
    "**/*.ts",
    "**/*.tsx",
    ".expo/types/**/*.ts",
    "expo-env.d.ts"
  ]
}

Thanks!

Steps to Reproduce

Check out and run storybook in the example repo

Snack or Repository Link

https://github.com/a16n-dev/uniwind-storybook-repro

Uniwind version

1.2.2

React Native Version

0.81.5

Platforms

Web

Expo

None

Additional information

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions