Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expo SDK 49 web (with metro) not working with react-hook-form #23322

Closed
fuelkoy opened this issue Jul 6, 2023 · 25 comments
Closed

Expo SDK 49 web (with metro) not working with react-hook-form #23322

fuelkoy opened this issue Jul 6, 2023 · 25 comments
Labels
needs review Issue is ready to be reviewed by a maintainer

Comments

@fuelkoy
Copy link

fuelkoy commented Jul 6, 2023

Minimal reproducible example

Had before. I seemly deleted it after some point

Summary

Template project from "https://docs.expo.dev/routing/installation/" and upgrading app according to "https://blog.expo.dev/expo-sdk-49-c6d398cdf740".

npm run web > blank page with following error in terminal:

  1. Unable to resolve "react-hook-form" from "app\(tabs)\index.tsx",

and in chrome console:

  1. Failed to load resource: the server responded with a status of 500 (Internal Server Error)
  2. Refused to execute script from 'http://localhost:8081/index.ts.bundle?platform=web&dev=true&hot=false&lazy=true' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.

Environment

expo-env-info 1.0.5 environment info:
System:
OS: Windows 10 10.0.19045
Binaries:
Node: 18.14.2 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.19 - ~\AppData\Local\pnpm\yarn.CMD
npm: 9.5.0 - C:\Program Files\nodejs\npm.CMD
npmPackages:
expo: ^49.0.0 => 49.0.0
react: 18.2.0 => 18.2.0
react-dom: 18.2.0 => 18.2.0
react-native: 0.72.1 => 0.72.1
react-native-web: ~0.19.6 => 0.19.6
Expo Workflow: managed

@fuelkoy fuelkoy added the needs validation Issue needs to be validated label Jul 6, 2023
@expo-bot expo-bot added needs review Issue is ready to be reviewed by a maintainer and removed needs validation Issue needs to be validated labels Jul 6, 2023
@Briseus
Copy link

Briseus commented Jul 6, 2023

just hit the same issue while upgrading from 48 to 49

@lenmazzone
Copy link

lenmazzone commented Jul 6, 2023

I added the following line to my metro.config.ts to resolve this:

config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];

The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

@fuelkoy
Copy link
Author

fuelkoy commented Jul 6, 2023

@lenmazzone works perfectly!
Thank you for sharing. I don't know how Expo team should take account of this, but at least now they have the knowledge of the problem (and react-hook-form could be pretty well used package) and also the solution

Related to #23180 (as including mjs (and cjs?) as default metro config should resolve the issue)

@robertherber
Copy link
Contributor

robertherber commented Jul 13, 2023

Related issue for urql: urql-graphql/urql#3313

The same metro.config.js trick fixed this for urql 👍 I guess it would make sense to make this part of the default metro.config.js?

@gorbypark
Copy link
Contributor

gorbypark commented Jul 14, 2023

I added the following line to my metro.config.ts to resolve this:

config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];

The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

This got me past the react-hook-forms error, but now I'm getting a new error about GestureHandler and the Drawer. This is only happening on web. I'm not quite sure what's going on tbh, possibly the above fix is not handling platform specific extensions? It's hard to say what's happening behind the scenes with all the transpiling and etc...

Web Bundling failed 1120ms
Unable to resolve "react-native-web/dist/exports/DrawerLayoutAndroid" from "node_modules/react-native-gesture-handler/lib/module/components/GestureComponents.web.js"

EDIT
This seems to be a separate problem

@andreiascendia
Copy link

I added the following line to my metro.config.ts to resolve this:
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

This got me past the react-hook-forms error, but now I'm getting a new error about GestureHandler and the Drawer. This is only happening on web. I'm not quite sure what's going on tbh, possibly the above fix is not handling platform specific extensions? It's hard to say what's happening behind the scenes with all the transpiling and etc...

Web Bundling failed 1120ms
Unable to resolve "react-native-web/dist/exports/DrawerLayoutAndroid" from "node_modules/react-native-gesture-handler/lib/module/components/GestureComponents.web.js"

EDIT This seems to be a separate problem

Any success with he hook problem?

@nasir733
Copy link

just ran into the same issue

@ysheep-js
Copy link

I added the following line to my metro.config.ts to resolve this:
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

This got me past the react-hook-forms error, but now I'm getting a new error about GestureHandler and the Drawer. This is only happening on web. I'm not quite sure what's going on tbh, possibly the above fix is not handling platform specific extensions? It's hard to say what's happening behind the scenes with all the transpiling and etc...

Web Bundling failed 1120ms
Unable to resolve "react-native-web/dist/exports/DrawerLayoutAndroid" from "node_modules/react-native-gesture-handler/lib/module/components/GestureComponents.web.js"

EDIT This seems to be a separate problem

Just the same issue

@gorbypark
Copy link
Contributor

gorbypark commented Jul 17, 2023

I added the following line to my metro.config.ts to resolve this:
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

This got me past the react-hook-forms error, but now I'm getting a new error about GestureHandler and the Drawer. This is only happening on web. I'm not quite sure what's going on tbh, possibly the above fix is not handling platform specific extensions? It's hard to say what's happening behind the scenes with all the transpiling and etc...

Web Bundling failed 1120ms
Unable to resolve "react-native-web/dist/exports/DrawerLayoutAndroid" from "node_modules/react-native-gesture-handler/lib/module/components/GestureComponents.web.js"

EDIT This seems to be a separate problem

Just the same issue

This is an unrelated issue, but all I had to do was npx expo install react-native-gesture-handler. @andreiascendia @nasir733

@dben89x
Copy link

dben89x commented Jul 30, 2023

I added the following line to my metro.config.ts to resolve this:
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

This got me past the react-hook-forms error, but now I'm getting a new error about GestureHandler and the Drawer. This is only happening on web. I'm not quite sure what's going on tbh, possibly the above fix is not handling platform specific extensions? It's hard to say what's happening behind the scenes with all the transpiling and etc...

Web Bundling failed 1120ms
Unable to resolve "react-native-web/dist/exports/DrawerLayoutAndroid" from "node_modules/react-native-gesture-handler/lib/module/components/GestureComponents.web.js"

EDIT This seems to be a separate problem

@gorbypark any success with the DrawerLayoutAndroid issue? I'm getting almost an identical error:

Unable to resolve "react-native-web/dist/exports/DrawerLayoutAndroid" from "node_modules/react-native-gesture-handler/src/components/GestureComponents.tsx"

Only difference is GestureComponents.tsx vs GestureComponents.web.js.

@balgamat
Copy link

I had "mjs" and "cjs" extensions in metro config already so I haven't noticed any problems... that is until I tried to bundle for the web:
image

I simply cannot get hook form going for the web...

@LinusU
Copy link
Contributor

LinusU commented Aug 26, 2023

I believe that this is the problem: 6a750d0#r121599931

Adding mjs and cjs to watcher.additionalExts seems to resolve the issue

@noledev
Copy link

noledev commented Aug 27, 2023

Thanks! Adding the extensions worked for me as well.

For those experiencing the DrawerLayoutAndroid issue, I also got this when updating to Expo 49. react-native-web@0.19.0 removed this component, but my version of react-native-gesture-handler was still referencing it. Updating to the latest (v2.12.1) resolved that error for me.

@Ernest2026
Copy link

balgamat

Hi balgamat, have you found a solution for this yet, I'm having similar issue, and I'll need to access the web to write test. Let me know if you have a workaround or you've found the solution, thanks in advance...

@simoazzo
Copy link

I added the following line to my metro.config.ts to resolve this:

config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];

The whole thing:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

// Remove all console logs in production...
config.transformer.minifierConfig.compress.drop_console = true;
config.resolver.sourceExts = [...config.resolver.sourceExts, "mjs", "cjs"];
module.exports = config;

This fixes the issue. Thank you @lenmazzone

@OneHatRepo
Copy link

I've got the same issue as @balgamat, and it's preventing me from using React Hook Form and Metro together on the web. This consequently prevents me from using Expo Router, which depends upon Metro!

package.json:

{
  "name": "my-app",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "web": "npx expo start --clear --web -p 8083",
    "build": "npx expo export -p web",
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios"
  },
  "dependencies": {
    "expo": "~49.0.15",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.49.2",
    "react-native": "0.72.6",
    "react-native-safe-area-context": "4.6.3",
    "react-native-safe-area-view": "^1.1.1",
    "react-native-web": "~0.19.6"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

metro.config.js:

const { getDefaultConfig } = require('expo/metro-config');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname, {
	// Enable CSS support.
	isCSSEnabled: true,
});

config.resolver.sourceExts.push('mjs', 'cjs');
config.resolver.assetExts.push('mjs', 'cjs');
config.watcher.additionalExts.push('mjs', 'cjs');

module.exports = config;

Error:

Uncaught TypeError: (0 , _reactHookForm.useForm) is not a function

@Ernest2026
Copy link

I've got the same issue as @balgamat, and it's preventing me from using React Hook Form and Metro together on the web. This consequently prevents me from using Expo Router, which depends upon Metro!

package.json:

{
  "name": "my-app",
  "version": "1.0.0",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "web": "npx expo start --clear --web -p 8083",
    "build": "npx expo export -p web",
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios"
  },
  "dependencies": {
    "expo": "~49.0.15",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-hook-form": "^7.49.2",
    "react-native": "0.72.6",
    "react-native-safe-area-context": "4.6.3",
    "react-native-safe-area-view": "^1.1.1",
    "react-native-web": "~0.19.6"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}

metro.config.js:

const { getDefaultConfig } = require('expo/metro-config');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname, {
	// Enable CSS support.
	isCSSEnabled: true,
});

config.resolver.sourceExts.push('mjs', 'cjs');
config.resolver.assetExts.push('mjs', 'cjs');
config.watcher.additionalExts.push('mjs', 'cjs');

module.exports = config;

Error:

Uncaught TypeError: (0 , _reactHookForm.useForm) is not a function

I had similar issues, I was able to fix it by just adding webpack bundler, I think expo 49 is not really compatible with react-hook-form most especially on the web

@OneHatRepo
Copy link

I have them working together fine on iOS & Android, but not on web.

@Hiba-Bazerbashi
Copy link

Hiba-Bazerbashi commented Jan 1, 2024

I have same issue with expo 49 managed
"expo": ^49.0.21,
"react-hook-form": ^7.49.2,
"@hookform/error-message": ^2.0.1,
"@hookform/resolvers": ^3.3.3,

metro.config.ts

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

module.exports = (() => {
  const config = getDefaultConfig(__dirname );
  const { transformer, resolver } = config;
  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve("react-native-svg-transformer")
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext:any) => ext !== "svg"),
    sourceExts: [...resolver.sourceExts, "svg"]
  };
  config.resolver.sourceExts.push('cjs');
  config.resolver.sourceExts.push('mjs');
  return config;
})();

on web I got this error

Unable to resolve "react-hook-form" from "src\screens\authScreens\signUpScreen\SignUpScreen.tsx"
and
import { ErrorMessage } from "@hookform/error-message"; give that error :
Unable to resolve "react-hook-form" from "node_modules@hookform\error-message\dist\index.esm.js"
also
import { yupResolver } from '@hookform/resolvers/yup'; give :
Unable to resolve "react-hook-form" from "node_modules@hookform\resolvers\yup\dist\yup.module.js"

on browser
Refused to execute script from 'http://localhost:8081/index.ts.bundle?platform=web&dev=true&hot=false&lazy=true' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.
on android just stuck in splash screen

any solution suggested ??

@OneHatRepo
Copy link

I was able to get them working together on web by switching to webpack bundler instead of metro. There seems to be a fundamental incompatibility between metro for web and react-hook-form.

@EvanBacon
Copy link
Contributor

We have added mjs support in Expo SDK 50, this should resolve the issue.

@hadiDanial
Copy link

Is there a fix for this for React Native Web?
It's working for native, but it won't compile for web, giving the error:
"Web Bundling failed
Unable to resolve "react-hook-form" from "path\to\file\SignInScreen.tsx" "

I can't upgrade to Expo SDK 50 right now since it caused other issues in the project.

Were you able to fix this, @Hiba-Bazerbashi ?

@Hiba-Bazerbashi
Copy link

Hiba-Bazerbashi commented Feb 6, 2024 via email

@gorbypark
Copy link
Contributor

Is there a fix for this for React Native Web? It's working for native, but it won't compile for web, giving the error: "Web Bundling failed Unable to resolve "react-hook-form" from "path\to\file\SignInScreen.tsx" "

I can't upgrade to Expo SDK 50 right now since it caused other issues in the project.

Were you able to fix this, @Hiba-Bazerbashi ?

@Hiba-Bazerbashi @hadiDanial Can you post your metro.config.js? I have a project on SDK49 and using expo web (expo-router/metro based) and the solution provided at the top of this issue works for me. Here is my metro.config.js, there's a number of ways to accomplish it, but you just have to make sure you are adding the mjs extension so metro knows to bundle them. You will also have to make sure to restart metro and clear the cache after making changes.

/* eslint-disable no-undef */
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

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

module.exports = (async () => {
  const {
    resolver: { sourceExts },
  } = config;

  return {
    ...config,
    resolver: {
      ...config.resolver,
      sourceExts: [...sourceExts, 'mjs'],
    },
  };
})();

@hadiDanial
Copy link

@gorbypark That worked!
I'm not familiar with Metro, and I had the config in a .ts file, and you said .js, so I just checked and according to metrobundler.dev:

A Metro config can be created in these three ways (ordered by priority):

metro.config.js
metro.config.json
The metro field in package.json

Chuck it up to a beginner mistake. Your config works perfectly, thanks mate ^^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs review Issue is ready to be reviewed by a maintainer
Projects
None yet
Development

No branches or pull requests