expo / web-examples

Examples of using Expo in the browser.
273 stars 54 forks source link

[Web] Previous Expo 36 app `Can't resolve '../Utilities/Platform'` #73

Open jonathanstiansen opened 4 years ago

jonathanstiansen commented 4 years ago

Expo Diagnostics

  Expo CLI 3.11.7 environment info:
    System:
      OS: Linux 4.15 Ubuntu 18.04.3 LTS (Bionic Beaver)
      Shell: 4.4.20 - /bin/bash
    Binaries:
      Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
      npm: 6.11.1 - ~/.nvm/versions/node/v10.16.3/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    npmPackages:
      @types/react: ^16.9.11 => 16.9.16 
      @types/react-native: ^0.60.22 => 0.60.25 
      @xstate/react: ^0.8.1 => 0.8.1 
      expo: ^36.0.0 => 36.0.0 
      react: 16.9.0 => 16.9.0 
      react-native: https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz => 0.61.4 
      react-navigation: ^3.11.1 => 3.13.0 
    npmGlobalPackages:
      expo-cli: 3.11.7

It's a mixed TS and JS project, using babel for the TS and JS.

Here's my webpack config:

const path = require('path')
const createExpoWebpackConfigAsync = require('@expo/webpack-config')

// source: https://docs.expo.io/versions/latest/guides/customizing-webpack/
// Expo CLI will await this method so you can optionally return a promise.
module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv)
  if (config.mode === 'development') {
    config.devServer.compress = false
  }

  // Or prevent minimizing the bundle when you build.
  if (config.mode === 'production') {
    config.optimization.minimize = false
  }
  config.resolve = {
    extensions: [".ts", ".tsx", ".js", ".json"]
  }
  config.module.rules = [{
    // Include ts, tsx, js, and jsx files.
    test: /\.(ts|jsx|js)x?$/,
    // exclude: /node_modules/,
    loader: 'babel-loader'
  }]
  return config
}

Here's my babel.config.js in the expo project:

module.exports = function (api) {
  api.cache(true)
  return {
    presets: ['babel-preset-expo', 'module:react-native-dotenv', '@babel/preset-typescript'],
    plugins: ['@babel/plugin-transform-react-jsx-source']
  }
}

When I run expo start:web I get this:

/home/mygastank/WebstormProjects/mygastank/customer/node_modules/react-native/Libraries/Image/AssetSourceResolver.js
Module not found: Can't resolve '../Utilities/Platform' in '/home/mygastank/WebstormProjects/mygastank/customer/node_modules/react-native/Libraries/Image'

My understanding from babel is that it would shake our incompatible modules. Do I need to be changing all of my import {View} from 'react-native' to import {View} from 'react-native-web'? Same with image (as the error seems to suggest?)

There doesn't seem to be a migration guide of any sort, so I'm uncertain how to get a previous expo app into web.

Any ideas?

EvanBacon commented 4 years ago

You may have a package that isn't being transpiled properly referencing react-native-web. Your webpack config seems to be copying a lot of the features @expo/webpack-config already provides. I'd recommend using the following to debug production builds:

EXPO_WEB_DEBUG=true expo build:web
jonathanstiansen commented 4 years ago

@EvanBacon when I run that, I don't get much output:

jono-vm:~/me/customer$ EXPO_WEB_DEBUG=true expo build:web
Bundling the project in debug mode.
  build [==============      ] 70% web  Failed to compile.

Module not found: Error: Can't resolve '../Utilities/Platform' in '/home/me/customer/node_modules/react-native/Libraries/Image'
Set EXPO_DEBUG=true in your env to view the stack trace.

I ensured that I have the latest CLI version.

atayahmet commented 4 years ago

Hi @jonathanstiansen

I'm facing same problem. Have you found any solution to this problem?

jonathanstiansen commented 4 years ago

@atayahmet Nope we just gave up on expo web. Seems like there isn't a good story for any serious Expo apps to use it. Too bad :-(

LukasGerm commented 4 years ago

Hey, I am getting the same problem after updating from expo 36 to 37.

igorbrandao commented 4 years ago

+1 having this issue.

In my case, I get it when I run expo start --webon my project:

web  Failed to compile.
./node_modules/react-native/Libraries/Components/TextInput/TextInputState.js
Module not found: Can't resolve '../../Utilities/Platform' in './node_modules/react-native/Libraries/Components/TextInput'

A quick note on this comment:

You may have a package that isn't being transpiled properly referencing react-native-web. Your webpack config seems to be copying a lot of the features @expo/webpack-config already provides. I'd recommend using the following to debug production builds:

EXPO_WEB_DEBUG=true expo build:web

I believe that the correct flag is EXPO_DEBUG=true, isn't it @EvanBacon ? Initially I ran as you suggested and the expo-cli prints default info and says Set EXPO_DEBUG=true in your env to view the stack trace.

Running again as per expo-cli recommendation, I got a stacktrace:

➜$ EXPO_DEBUG=true expo build:web 

● Expo Webpack █████████████████████████ building (70%) 80/122 modules 42 active
 babel-loader › src/store/reducers/bank.js

 web  Failed to compile.

Module not found: Error: Can't resolve 'react-native-web/dist/exports/AsyncStorage' in './src/store'
Error: Module not found: Error: Can't resolve 'react-native-web/dist/exports/AsyncStorage' in './src/store'
    at /@expo/xdl@57.8.21/src/Webpack.ts:268:23
    at finalCallback (/Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/webpack/lib/Compiler.js:257:39)
    at onCompiled (/Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/webpack/lib/Compiler.js:265:20)
    at /Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/webpack/lib/Compiler.js:660:21
    at eval (eval at create (/Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:92:1)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Even though expo build:web threw a totally different error from the one that expo start --web points out, both are related to react-native core components (TextInput and AsyncStorage). Any ideas on how to get these compilation failures resolved?

olukayodea commented 4 years ago

@igorbrandao , you'll have to downgrade to react-native-web 0.11.7, react native no longer packages AsyncStorage but react-native-web hasn't upgraded yet.

bwalsh commented 4 years ago

Running into the same problem.

    "react-native": "https://github.com/expo/react-native/archive/sdk-37.0.0.tar.gz",
    "react-native-gesture-handler": "~1.6.0",
    "react-native-material-dropdown-v3": "https://github.com/mikedizon/react-native-material-dropdown",
    "react-native-paper": "^3.7.0",
    "react-native-reanimated": "~1.7.0",
    "react-native-safe-area-context": "0.7.3",
    "react-native-screens": "~2.2.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-web": "~0.11.7",
igorbrandao commented 4 years ago

@olukayodea thanks for the tip! While downgrading to rn-web to 0.11.7 corrected the AsyncStorage compilation error I was having before, its not quite there yet. It now crashed a little further down the road. The culprit this time is TextInput module of RN core (the same error I am having when running expo start --web):

● Expo Webpack █████████████████████████ building (70%) 1589/1613 modules 24 active
 node_modules/lodash/_isFlattenable.js

 web  Failed to compile.

Module not found: Error: Can't resolve '../../Utilities/Platform' in './node_modules/react-native/Libraries/Components/TextInput'
Error: Module not found: Error: Can't resolve '../../Utilities/Platform' in './node_modules/react-native/Libraries/Components/TextInput'
    at /@expo/xdl@57.8.22/src/Webpack.ts:268:23
    at finalCallback (/Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/webpack/lib/Compiler.js:257:39)
    at onCompiled (/Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/webpack/lib/Compiler.js:265:20)
    at /Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/webpack/lib/Compiler.js:660:21
    at eval (eval at create (/Users/ibrandao/.nvm/versions/node/v13.8.0/lib/node_modules/expo-cli/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:92:1)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Any tips on that one?

croossin commented 4 years ago

@igorbrandao I'm running into the same issue as you!

ricardoribas commented 4 years ago

It seems that there might be an issue with internal libraries of RN when using react-native-web. If i use the normal RN component it seems to be working just fine. If i try to use more dependencies, those kind of errors pop up.

lc3t35 commented 4 years ago

Same for me SDK37 Module not found: Can't resolve '../../Utilities/Platform' in '/xxxx/node_modules/react-native/Libraries/Components/TextInput'

Expo CLI 3.18.6 environment info:
    System:
      OS: macOS High Sierra 10.13.6
      Shell: 3.2.57 - /bin/bash
    Binaries:
      Node: 10.15.0 - /usr/local/bin/node
      Yarn: 1.22.4 - ~/.yarn/bin/yarn
      npm: 6.11.3 - /usr/local/bin/npm
      Watchman: 4.7.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.3 AI-182.5107.16.33.5314842
      Xcode: 10.1/10B61 - /usr/bin/xcodebuild
    npmPackages:
      expo: ^37.0.0 => 37.0.7 
      react: ~16.9.0 => 16.9.0 
      react-native: https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz => 0.61.4 
    npmGlobalPackages:
      expo-cli: 3.18.6
ricardoribas commented 4 years ago

I turned out to solve this problem by using the module resolver plugin and doing some custom logic. If you are using monorepo, most probably you need to resolve it to the root of the project node modules.

cmaycumber commented 4 years ago

@ricardoribas What exactly did you resolve? I'm running into this exact issue in a monorepo using yarn workspaces and expo-yarn-workspaces.

ricardoribas commented 4 years ago

You might have a dependency that is using react native. RNW do not resolve relative paths 100%. I installed this plugin and on the webpack config I configure the plugin to resolve to the RNW exports. I will prepare a snippet asap.

cmaycumber commented 4 years ago

@ricardoribas Thanks much appreciated.

ricardoribas commented 4 years ago

In my particular case, i installed the module-resolver plugin. This was a life savior. Otherwise you would need to create your own babel plugin. I am actually curious about the whole process of (1) developing, (2) debugging and (3) publishing plugins. Going to the point!

To fix the paths problems, you need to override some configurations that CRA provides. I installed react-app-rewired package in order to create a custom configuration. I've added this snippet

[
    'module-resolver',
    {
      root: ['./src'],
      resolvePath(sourcePath, currentFile, ...otherparams /* opts */) {
        return resolvePath(sourcePath, currentFile, otherparams);
      },
      loglevel: 'verbose'
    }
]

in the webpack plugins object (config -> module -> rules[2] -> oneOf[1] -> options -> plugins). This is my configuration:

/* eslint-disable no-param-reassign */
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);

const PACKAGES = [
    MY-PACKAGES
];
const NODE_MODULES_WHITELIST = [
  MY-NODE_MODULES-THAT-NEED-TRANSFORMATION
];

const appIncludes = [
  resolveApp('src'),
  ...PACKAGES.map((p) => resolveApp(`../${p}/src`)),
  ...NODE_MODULES_WHITELIST.map((m) => resolveApp(`../../node_modules/${m}`))
];

module.exports = function override(config, env) {
  config.module.strictExportPresence = false;

  // resolve config alias
  delete config.resolve.alias['react-native'];

  // CRA actually has a problem with libraries. You need to include libraries
  // that finish with react-native (react-native-device-info is wrong for instance)
  config.resolve.alias['react-native$'] = 'react-native-web';

  // allow importing from outside of src folder
  config.resolve.plugins = config.resolve.plugins.filter(
    (plugin) => plugin.constructor.name !== 'ModuleScopePlugin'
  );
  config.module.rules[0].include = appIncludes;
  config.module.rules[1] = null;
  config.module.rules[2].oneOf[1].include = appIncludes;
  config.module.rules[2].oneOf[1].options.presets = [
    'module:react-native-dotenv',
    require.resolve('@babel/preset-react')
  ].concat(config.module.rules[2].oneOf[1].options.presets);
  config.module.rules[2].oneOf[1].options.plugins = [
    require.resolve('babel-plugin-transform-react-remove-prop-types'),
    require.resolve('@babel/plugin-transform-flow-strip-types'),
    require.resolve('@babel/plugin-proposal-class-properties'),
    require.resolve('babel-plugin-react-native-web'),
    [
      'module-resolver',
      {
        root: ['./src'],
        resolvePath(sourcePath, currentFile, ...otherparams /* opts */) {
          // Need to check if the source path is ../../Platform and if the currentFile belongs to the react native module to prevent conflicts
          // Then you can resolve (return as a string) to the path that you want.
          return resolvePath(sourcePath, currentFile, otherparams);
        },
        loglevel: 'verbose'
      }
    ]
  ].concat(config.module.rules[2].oneOf[1].options.plugins);
  config.module.rules = config.module.rules.filter(Boolean);

  config.plugins.push(
    new webpack.DefinePlugin({ __DEV__: env !== 'production' }),
    // Some old stuff is not compatible with new versions of RNWeb
    new webpack.NormalModuleReplacementPlugin(
      new RegExp(
        'node_modules/react-native-vector-icons/lib/toolbar-android.js'
      ),
      path.resolve('./config/toolbar.android.js')
    )
  );

  return config;
};

Feel free to remove whatever you don't need. I hope it works for you.

lc3t35 commented 4 years ago

@ricardoribas Thank you for sharing this configuration but I don't understand the process, can you clarify the steps :

Maybe you can edit your previous post ? Thank you.

ricardoribas commented 4 years ago

CRA is using a webpack config. You can check the node modules for webpack.config.js. the values that I am customizing in the file are related to that config.

The resolve path method is a custom one. Basically it has some ifs for the cases that do work. The plugin requires a string of the path to be returned.

lc3t35 commented 4 years ago

@ricardoribas I can't find any webpack.config.js in node_modules. can you please detail the path where it should be ? or I must create one ? I don't have to add "module-resolver" in babel.config.js, but only in the webpack config, right ? I've updated my previous comment.

omerts commented 4 years ago

Seems to be an issue due to the fact that platform is only exported as platform-specific export, aka as iOS and Android only. Screen Shot 2020-05-12 at 2 06 45 I have seen this same issue come up in react-native-scrollable-tab-view, with the Button import, as well.

DmitryKvant commented 4 years ago

please help, I get same problem. Upgrading to expo v37 not resolve it issue

lc3t35 commented 4 years ago

@ricardoribas can you please detail your solution, here are the unsolved questions :
I can't find any webpack.config.js in node_modules. can you please detail the path where it should be ? or I must create one ? I don't have to add "module-resolver" in babel.config.js, but only in the webpack config, right ? I've updated my previous comment.

ricardoribas commented 4 years ago

I will make a repo and share with you guys. Maybe is the best way to explain how I solve it.

ksairi commented 4 years ago

@ricardoribas thank you for your help! Looking forward to your solution. I'm having the same issue using expo SDK 37 and "react-native-web": "^0.11.7" I was alredy using the module resolver plugin and this is my babel.config.js:

module.exports = (api) => {
  api.cache(true);
  return {
    presets: ["babel-preset-expo"],
    plugins: [
      [
        "module-resolver",
        {
          root: ["./app"],
          extensions: [".js", ".ios.js", ".android.js"],
        },
      ],
      ["@babel/plugin-syntax-class-properties"],
    ],
  };
};
ksairi commented 4 years ago

@ricardoribas and all: I kept searching and found that expo comes with a built-in way to override webpack's config here. The thing is I tried @ricardoribas solution in many ways (adding the plugin as an array and object) (I think object is the right way) and it keeps returning this:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.plugins[11] misses the property 'apply'.
   function
   -> The run point of the plugin, required method.

This is my webpack.config.js :

{
  mode: 'development',
  entry: [AsyncFunction],
  bail: false,
  devtool: 'cheap-module-source-map',
  context: '/Users/directoco/workspace/galaApp/node_modules/@expo/webpack-config/webpack',
  output: {
    publicPath: '/',
    path: '/Users/directoco/workspace/galaApp/web-build',
    globalObject: 'this',
    pathinfo: true,
    filename: 'static/js/bundle.js',
    chunkFilename: 'static/js/[name].chunk.js',
    devtoolModuleFilenameTemplate: [Function]
  },
  plugins: [
    HtmlWebpackPlugin {
      options: [Object],
      childCompilerHash: undefined,
      childCompilationOutputName: undefined,
      assetJson: undefined,
      hash: undefined,
      version: 4
    },
    InterpolateHtmlPlugin {
      htmlWebpackPlugin: [Function: HtmlWebpackPlugin],
      replacements: [Object]
    },
    ExpoPwaManifestWebpackPlugin {
      options: [Object],
      writeObject: [AsyncFunction],
      pwaOptions: [Object]
    },
    FaviconWebpackPlugin {
      modifyOptions: {},
      pwaOptions: [Object],
      favicon: [Object]
    },
    ModuleNotFoundPlugin {
      appPath: '/Users/directoco/workspace/galaApp',
      yarnLockFile: undefined,
      useYarnCommand: [Function: bound useYarnCommand],
      getRelativePath: [Function: bound getRelativePath],
      prettierError: [Function: bound prettierError]
    },
    DefinePlugin { definitions: [Object] },
    HotModuleReplacementPlugin {
      options: {},
      multiStep: undefined,
      fullBuildTimeout: 200,
      requestTimeout: 10000
    },
    WatchMissingNodeModulesPlugin {
      nodeModulesPath: '/Users/directoco/workspace/galaApp/node_modules'
    },
    ManifestPlugin { opts: [Object] },
    WebpackBar {
      profile: false,
      handler: [Function],
      modulesCount: 500,
      showEntries: false,
      showModules: true,
      showActiveModules: true,
      options: [Object],
      reporters: [Array]
    },
    CopyPlugin { patterns: [Array], options: {} },
    { 'module-resolver': [Object] }
  ],
  module: { strictExportPresence: false, rules: [ [Object], [Object] ] },
  resolveLoader: { plugins: [ [Object] ] },
  resolve: {
    mainFields: [ 'browser', 'module', 'main' ],
    extensions: [
      '.web.ts',  '.web.tsx',
      '.web.mjs', '.web.js',
      '.web.jsx', '.ts',
      '.tsx',     '.mjs',
      '.js',      '.jsx',
      '.json',    '.wasm'
    ],
    plugins: [ [Object] ],
    symlinks: false,
    alias: {
      'react-native$': 'react-native-web',
      'react-native/Libraries/Components/View/ViewStylePropTypes$': 'react-native-web/dist/exports/View/ViewStylePropTypes',
      'react-native/Libraries/EventEmitter/RCTDeviceEventEmitter$': 'react-native-web/dist/vendor/react-native/NativeEventEmitter/RCTDeviceEventEmitter',
      'react-native/Libraries/vendor/emitter/EventEmitter$': 'react-native-web/dist/vendor/react-native/emitter/EventEmitter',
      'react-native/Libraries/vendor/emitter/EventSubscriptionVendor$': 'react-native-web/dist/vendor/react-native/emitter/EventSubscriptionVendor',
      'react-native/Libraries/EventEmitter/NativeEventEmitter$': 'react-native-web/dist/vendor/react-native/NativeEventEmitter',
      '@react-native-community/netinfo': 'react-native-web/dist/exports/NetInfo',
      'react-native/Libraries/Image/AssetSourceResolver$': 'expo-asset/build/AssetSourceResolver',
      'react-native/Libraries/Image/assetPathUtils$': 'expo-asset/build/Image/assetPathUtils',
      'react-native/Libraries/Image/resolveAssetSource$': 'expo-asset/build/resolveAssetSource'
    }
  },
  performance: { maxAssetSize: 600000, maxEntrypointSize: 600000 },
  devServer: {
    compress: true,
    clientLogLevel: 'none',
    contentBase: '/Users/directoco/workspace/galaApp/node_modules/@expo/webpack-config/web-default',
    watchContentBase: true,
    hot: true,
    publicPath: '/',
    quiet: true,
    host: '0.0.0.0',
    overlay: false,
    historyApiFallback: { disableDotRule: true },
    public: undefined,
    proxy: undefined,
    before: [Function: before],
    https: false,
    disableHostCheck: true,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
      'Access-Control-Allow-Headers': 'X-Requested-With, content-type, Authorization'
    }
  },
  node: {
    module: 'empty',
    dgram: 'empty',
    dns: 'mock',
    fs: 'empty',
    http2: 'empty',
    net: 'empty',
    tls: 'empty',
    child_process: 'empty'
  }
}

And this is where I override webpack.config.js:

const createExpoWebpackConfigAsync = require("@expo/webpack-config");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  // Customize the config before returning it.
  config.plugins.push({
    "module-resolver": {
      root: ["./app"],
      resolvePath(sourcePath, currentFile, ...otherparams /* opts */) {
        return resolvePath(sourcePath, currentFile, otherparams);
      },
      loglevel: "verbose",
    },
  });
  return config;
};

My guts tell me that we should add some aliases to overcome this. Ideas?

ksairi commented 4 years ago

I continued digging and found out that this dependency: deprecated-react-native-listview was causing the problem. I had to add to add it to app.json like this:

"web": {
      "build": {
        "babel": {
          "include": [
            "deprecated-react-native-listview"
          ]
        }
      }
    },

and when I removed the dependency and that snippet from app.json, error was gone!

ricardoribas commented 4 years ago

I created a sample repository here: https://github.com/ricardoribas/expo-react-native-web As i mentioned before, the module resolver babel plugin will be super useful to resolve your dependencies problems. @ksairi thumbs up for sharing that piece of code as well. Bear in mind that the configuration of webpack that i've added is far from perfect. For sure i am forgetting about some build configurations. But the main goal as to explain how i solved that kind of issues.

It seems to me that the configuration of CRA is super complete. You can take also a look for some inspiration: https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/config/webpack.config.js

ChrisCruze commented 4 years ago

Thanks - i still seem to get the same error

yannvr commented 4 years ago

You might have a dependency that is using react native. RNW do not resolve relative paths 100%. I installed this plugin and on the webpack config I configure the plugin to resolve to the RNW exports. I will prepare a snippet asap.

That was indeed my issue using react-native-viewpager

lc3t35 commented 4 years ago

@ricardoribas @ksairi sorry but I still don't understand the process, can you please clarify the steps :

OK : install module resolver : yarn add --dev babel-plugin-module-resolver
OK : no need to modify existing babel.config.js
?? where is the webpack plugin file ?
?? how to find which dependency generates the issue ?
?? do we need react-app-rewired , how to configure it ?

I'm using expo sdk37.

ksairi commented 4 years ago

@lc3t35 go through your dependencies and try to remove old ones and see if that fixes the error. If that's the issue you should find newer ones. That was my problem, like I mentioned before

lc3t35 commented 4 years ago

@ksairi "remove old ones" : how can I find these "old ones" ? is there a "debug" mode which would print it ? I think people facing this issue needs a clear, repeatable process to identify and fix the issue. I don't have enough knowledge to do it, thank you for your help 👍

questions still open are : ?? where is the webpack plugin file ? ?? how to find which dependency generates the issue ?

aditya61085 commented 4 years ago

Same issue. Expo 3.21.5

web Failed to compile. C:/Aditya/Programming/ReactNativeStockProject/node_modules/react-native/Libraries/Components/TextInput/TextInputState.js Module not found: Can't resolve '../../Utilities/Platform' in 'C:\Aditya\Programming\ReactNativeStockProject\node_modules\react-native\Libraries\Components\TextInput'

Do not see this file: const Platform = require('../../Utilities/Platform');

ksairi commented 4 years ago

@lc3t35 the config file is generated as explained here. I couldn't see which dependency was causing the issue. I went all over my dependencies and checked how much time passed since the last release. Try to comment out the suspicious ones and see if the error goes away

shystruk commented 4 years ago

same issue, Expo 37 :(

lc3t35 commented 4 years ago

Status of research :

OK : install module resolver : yarn add --dev babel-plugin-module-resolver
OK : no need to modify existing babel.config.js
OK : webpack plugin file : create an empty file at root of the project named "webpack.config.js"
?? how to find which dependency generates the issue ?
?? do we need react-app-rewired , how to configure it ?
mustafashaikhly commented 4 years ago

I upgraded to Exp 38, and I'm still facing the same issue.

f4z3k4s commented 4 years ago

For me it was clearly an issue with the package I use and not with Expo itself. The package namely was

"@ant-design/react-native": "^4.0.0",

After removing the package from my project, expo web works brilliantly.

Edit: As I checked deeper it uses react-native-viewpager under the hood so I confirm it is likely an issue with that package. I even get a warning from Expo:

Some of your project's dependencies are not compatible with currently installed expo package version:
 - @react-native-community/viewpager - expected version range: 3.3.0 - actual version installed: ^4.0.1
Your project may not work correctly until you install the correct versions of the packages.
To install the correct versions of these packages, please run: expo install [package-name ...]
lc3t35 commented 4 years ago

@f4z3k4s you don't use the correct version of @react-native-community/viewpager. Not enough for our cases. The problem is how can we find which package has a problem with expo web ! As there is no information displayed about the origin of the issue. Did someone tryed in DEBUG mode ?

ricardoribas commented 4 years ago

The module resolver plugin can log the path of the file and import statement. There is an option of the plugin to use verbose mode. Of you start the packager without running the application and then start the application with the same packager, you should be able to see logs.

AlmondBro commented 4 years ago

I can concur to this issue as well. Expo-web builds do not seek to play nicely with relative paths. I am using Expo SDK 38, here is my package.json: { "main": "./src/index.js", "entryPoint": "./src/index.js", "name": "cvuhsd-portal-mobile", "version": "2.0.0", "scripts": { "start": "expo start", "start-reset": "rm -rf node_modules/ && npm install && npm audit fix && npm install && npm start --reset-cache", "publish": "expo publish", "build-android": "expo build:android", "upload-android": "expo upload:android", "expo-clean-start": "npm install -g expo-cli && rm -rf node_modules/ && npm cache clean --force && npm install expo@latest && expo install && expo start -c", "build-ios": "expo build:ios", "ios": "expo start --ios", "android": "expo start --android", "eject": "expo eject" }, "dependencies": { "@expo-google-fonts/inter": "^0.1.0", "@expo-google-fonts/source-sans-pro": "^0.1.0", "@react-native-community/async-storage": "~1.11.0", "@react-native-community/hooks": "^2.5.1", "@react-native-community/masked-view": "0.1.10", "@react-navigation/native": "^5.4.3", "@react-navigation/stack": "^5.4.0", "azure-ad-graph-expo": "github:JuanDavidLopez95/azure-ad-graph-expo", "expo": "^38.0.8", "expo-auth-session": "~1.4.0", "expo-blur": "~8.1.2", "expo-font": "~8.2.1", "expo-status-bar": "^1.0.0", "expo-updates": "~0.2.8", "greeting": "^1.0.6", "kind-of": "^6.0.3", "pod-install": "^0.1.6", "react": "16.11.0", "react-dom": "16.11.0", "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.2.tar.gz", "react-native-app-link": "^1.0.0", "react-native-collapsible": "^1.5.2", "react-native-expo-image-cache": "^4.1.0", "react-native-gesture-handler": "~1.6.0", "react-native-global-props": "^1.1.5", "react-native-modal": "^11.5.6", "react-native-reanimated": "~1.9.0", "react-native-safe-area-context": "~3.0.7", "react-native-safe-area-view": "^1.1.1", "react-native-screens": "~2.9.0", "react-native-svg": "12.1.0", "react-native-svg-transformer": "^0.14.3", "react-native-web": "~0.11.7", "react-native-webview": "9.4.0", "styled-components": "^5.1.0", "styled-css": "^1.1.0", "url": "^0.11.0" }, "devDependencies": { "@babel/core": "^7.8.6", "babel-preset-expo": "^8.2.3", "react-native-dotenv": "^0.2.0", "reactotron-react-native": "^5.0.0" }, "private": false }

image

lc3t35 commented 3 years ago

@JuanDavidLopez95 I don't think you have the same problem as you are trying to add specific assets to your project. The problem still here with SDK38 is about

xxx/node_modules/react-native/Libraries/Components/TextInput/TextInputState.js
Module not found: Can't resolve '../../Utilities/Platform' in '/xxx/node_modules/react-native/Libraries/Components/TextInput'

And there are only Platform.android.js and Platform.ios.js files in node_modules/react-native/Libraries/Utilities

So one module is using react-native/Libraries/Components/TextInput/TextInputState.js and not resolved thru react-native-web configuration. The open question is "how can we find directly which module it is ?".

Siyavoshi commented 3 years ago

My issue went away after replacing the content of my babel.config.js with:

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

My devDependencies: "devDependencies": { "@babel/core": "^7.8.6", "@babel/runtime": "^7.8.0", "@react-native-community/eslint-config": "^0.0.6", "babel-jest": "^24.9.0", "babel-preset-expo": "^8.2.3", "eslint": "^6.8.0", "jest": "^24.9.0", "metro-react-native-babel-preset": "^0.56.4", "react-test-renderer": "16.9.0" }

Hope this helps someone out.

pedro-surf commented 3 years ago

Hello, I'm very new to RN, I get the same issue when I try to open Expo App in web browser. Haven't done any configuration.

image

My package.json:

{
  "main": "node_modules/expo/AppEntry.js",
  "dependencies": {
    "@react-native-community/geolocation": "^2.0.2",
    "expo": "~39.0.2",
    "expo-status-bar": "~1.0.2",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-39.0.2.tar.gz",
    "react-native-orientation": "^3.1.3",
    "react-native-progress": "^4.1.2",
    "react-native-qrcode": "^0.2.7",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0"
  }
yesIamFaded commented 3 years ago

Is there a general guide on how to modify Webpack or some general steps that are needed to make your existing app work on Web? I have a medium large app and there is no chance that it can run like it is on web.

Would be cool if someone who managed to make their app run on the web could reproduce the steps he made and what there is to watch out.

Also where do you have your Webpack config?

ricardoribas commented 3 years ago

Are you using monorepo with lerna (with or without yarn) or standalone yarn? As the dependencies are being added to the root node_modules directory, you might have issues with webpack. You need to customize webpack to resolve the other node_modules. For yarn, i customized webpack configuration to always resolve to the root directory for RN based dependencies.

FabrizioFubelli commented 3 years ago

Hello guys,

The Type components (such as TextInput) should be referenced to @types/react-native package.

In my case the library react-native-vector-icons/FontAwesome5 was causing the problem.

So it works for me:

1. Install @types

npm install --save-dev typescript @types/jest @types/react @types/react-native @types/react-test-renderer

2. Removed annoying libraries

Removed usage of react-native-vector-icons/FontAwesome5 from all software

se22as commented 3 years ago

You might have a dependency that is using react native. RNW do not resolve relative paths 100%. I installed this plugin and on the webpack config I configure the plugin to resolve to the RNW exports. I will prepare a snippet asap.

That was indeed my issue using react-native-viewpager

This is exactly the issue I am having, if i remove react-native-viewpager from my app, my React Native App runs on the web perfectly fine.

But I am still stuck as I am not 100% clear on the solution. I created my application using expo.

Tried editing babel.config.js The default babel.config.js is

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

I edited it to be the following, but this made no difference, I still see the error for TextInput due to ViewPager

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: [
      [
        "module-resolver",
        {
          root: ["./app"],
          extensions: [".js", ".ios.js", ".android.js"],
        },
      ],
    ],
  };
};

webpack.config.js I ran expo customize:web and selected the webpack option, this command adds a webpack.config.js to my expo project whose contents are

const createExpoWebpackConfigAsync = require('@expo/webpack-config');

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  // Customize the config before returning it.
  return config;
};

I am not clear on what exactly I have to put in webpack.config.js to get the ViewPager to work properly. In ricardoribas repository it has

plugins: [
          [
            "module-resolver",
            {
              root: ["./src"],
              resolvePath(sourcePath, currentFile, ...otherparams /* opts */) {
                return resolvePath(sourcePath, currentFile, otherparams);
              },
              loglevel: "verbose",
            },
          ],
        ],

and resolve path contains

function resolvePath(sourcePath, currentFile, otherparams) {
  // add logic to resolve your source path to a new file
  // https://github.com/tleunen/babel-plugin-module-resolver

  // this can be used to solve different kind of problems
  // 1 - the specific library do not have an implementation for web, so you need to mock the file
  // 2 - the specific import is relative and you need to solve using the path API from nodeJS

  // undefined will not change the source path
  return undefined;
}

I have absolutely no idea what i should be adding to this resolvePath method

My project The relevant parts of my project are:

project root
  |- node_modules
      |- @react-native-community
         |- viewpager
           |- js
            |- ViewPager

      |- react-native
         |- Libraries
           |- Components
                 |- TextInput
           |- Utilities
                 |- Platform.android.js
                 |- Platform.ios.js         
                 <!-- obviously there is no platform for web, as react-native code is just for native devices

      |- react-native-web       
         |- src
           |- exports
                 |- Platform  <!-- this is the web version of Platform

Therefore is it the following i need to map?

../../Utilities/Platform

to

/react-native-web/src/exports/Platform

I tried updating my webpack.config.js to the following but it makes no difference.

const createExpoWebpackConfigAsync = require('@expo/webpack-config');
const paths = require("@expo/config/paths");

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  // Customize the config before returning it.

  config.module.rules = [
    {
      test: /\.(js|mjs|jsx|ts|tsx)$/,
      include: paths.getPossibleProjectRoot(),
      loader: require.resolve("babel-loader"),
      options: {
        plugins: [
          [
            "module-resolver",
            {
              root: ["./src"],
              alias: {
                "../../Utilities/Platform": "./react-native-web/src/exports/Platform",
              },
            },
          ],
        ],
      },
    },
  ];

  return config;
};
webjay commented 3 years ago

I see that there are the following files:

So I created an empty Platform.web.js file there, and the next error I see is Can't resolve './Button' in './node_modules/react-native-scrollable-tab-view' so I think Expo web is not yet for me :)

Perhaps Platform.web.js can be a lead for someone.