Skip to content
This repository has been archived by the owner on Jul 20, 2021. It is now read-only.

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

Open
jonathanstiansen opened this issue Feb 5, 2020 · 63 comments
Open

Comments

@jonathanstiansen
Copy link

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
Copy link
Collaborator

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
Copy link
Author

jonathanstiansen commented Feb 11, 2020

@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
Copy link

Hi @jonathanstiansen

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

@jonathanstiansen
Copy link
Author

@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
Copy link

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

@igorbrandao
Copy link

igorbrandao commented Apr 14, 2020

+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/[email protected]/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
Copy link

@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
Copy link

bwalsh commented Apr 16, 2020

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
Copy link

igorbrandao commented Apr 16, 2020

@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/[email protected]/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
Copy link

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

@ricardoribas
Copy link

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
Copy link

lc3t35 commented Apr 24, 2020

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
Copy link

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
Copy link

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

@ricardoribas
Copy link

ricardoribas commented Apr 24, 2020

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
Copy link

@ricardoribas Thanks much appreciated.

@ricardoribas
Copy link

ricardoribas commented Apr 29, 2020

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
Copy link

lc3t35 commented Apr 29, 2020

@ricardoribas Thank you for sharing this configuration but I don't understand the process, can you 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 ?
  • ?? do we need react-app-rewired , how to configure it ?

Maybe you can edit your previous post ? Thank you.

@ricardoribas
Copy link

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
Copy link

lc3t35 commented May 1, 2020

@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
Copy link

omerts commented May 11, 2020

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
Copy link

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

@lc3t35
Copy link

lc3t35 commented May 14, 2020

@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
Copy link

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

@ksairi
Copy link

ksairi commented May 14, 2020

@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
Copy link

ksairi commented May 15, 2020

@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
Copy link

ksairi commented May 16, 2020

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
Copy link

ricardoribas commented May 16, 2020

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
Copy link

Thanks - i still seem to get the same error

@yannvr
Copy link

yannvr commented May 23, 2020

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
Copy link

lc3t35 commented Jun 30, 2020

@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
Copy link

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
Copy link

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
Copy link

lc3t35 commented Jul 26, 2020

@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
Copy link

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
Copy link

pedro-surf commented Sep 30, 2020

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
Copy link

yesIamFaded commented Oct 5, 2020

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
Copy link

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
Copy link

FabrizioFubelli commented Oct 12, 2020

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
Copy link

se22as commented Oct 12, 2020

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
Copy link

webjay commented Nov 8, 2020

I see that there are the following files:

  • ./node_modules/react-native/Libraries/Utilities/Platform.android.js
  • ./node_modules/react-native/Libraries/Utilities/Platform.ios.js

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.

@nathan-remote
Copy link

nathan-remote commented Nov 25, 2020

For anyone experiencing this issue when using electron also, this is what worked for me:

Ensure you have an electron directory at the root of your project

Inside this directory, create a webpack.config.js file with the following contents:

const { withExpoWebpack } = require('@expo/electron-adapter');

module.exports = config => {

  let expoConfig = withExpoWebpack(config);
    
  expoConfig.resolve.alias['react-native$'] = 'react-native-web';
  
  return expoConfig;
};

If you get a subsequent error saying that babel-loader module can't be found, add it

Adding a resolve alias makes somewhat sense to me, because the non-platform specific files live within the react-native-web node module at ./react-native-web/src/exports/Platform/index.js

I had no luck with the module-resolver plugin either, this was the only approach that enables our app to compile

@francesco-clementi-92
Copy link

Any news on how to find out which package is generating the error?

It's impossible to check each one manually.

@RameshkrishnanV
Copy link

Is anyone fixed this issue?

@reactnewb
Copy link

reactnewb commented Jan 26, 2021

I followed this instruction by @webjay

I see that there are the following files:

  • ./node_modules/react-native/Libraries/Utilities/Platform.android.js
  • ./node_modules/react-native/Libraries/Utilities/Platform.ios.js

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 :)

And in my case it throws the following error.

/Users/rn/ex-items-app/node_modules/react-native/Libraries/StyleSheet/processColor.js
Module not found: Can't resolve './PlatformColorValueTypes' in '/Users/rn/ex-items-app/node_modules/react-native/Libraries/StyleSheet'

I'm trying to use the following package with the expo.
https://github.com/TheRealNate/meteor-react-native

And it doesn't use StyleSheet anywhere!

@Esxiel
Copy link

Esxiel commented Jan 28, 2021

For me it was the viewpager library as well, (https://github.com/callstack/react-native-viewpager)
I was on 4.2.0 and I suspect this import to be the cause

const ReactNative = require('react-native');
const {Platform, UIManager} = ReactNative;

I upgraded to 4.2.2 and it fixed itself.

Now I just need to figure out how to fix the other libraries...

@ibrahimansar
Copy link

Simply delete node-modules, package-lock.json and reinstall is working for me :)

@kanzitelli
Copy link

kanzitelli commented Feb 20, 2021

I have faced the same issue while trying to run the existing Expo app on the Web.

I have noticed that those files had only .ios.js and .android.js extensions, so I have added empty files with the same name but .web.js extension. And I got another error pointing to another file. Not sure if it's the right approach but in order to optimize this process, I have written a small script that runs on postinstall and adding missing files. After that, I have faced another issue from react-native-web but there was already the script for a workaround.

Here is a pre-configured project expo-starter that runs the app on Web out of the box. You can find the script here.
And this is the deployed version of the app on Vercel - app.expo.batyr.io.

Hope it helps 🙂

@Gerrist
Copy link

Gerrist commented Apr 2, 2021

@kanzitelli Your 'You can find the script here' link points to a 404. Would you mind re-uploading this file?

@kanzitelli
Copy link

@Gerrist there is probably no need for those scripts anymore as some libraries have been updated and that issue was fixed. However, if you'd like to check them out, here is the link - https://github.com/kanzitelli/expo-starter/tree/1.0.0/scripts.

@phamquyhai
Copy link

@kanzitelli i have same issue,
i try your script, but not working.
do u have any idea for this. what this bug ?

/Users/pham.quy.hai/WorkSpace/mini-kiss/miwa-v2/miwa/node_modules/react-native/Libraries/LogBox/UI/LogBoxNotification.js
Module not found: Can't resolve '../../Image/Image' in '/Users/pham.quy.hai/WorkSpace/mini-kiss/miwa-v2/miwa/node_modules/react-native/Libraries/LogBox/UI'

@kanzitelli
Copy link

@phamquyhai hi there! So this error comes out when there is no file as Image.web.js, so what the script does is creating missing files with .web.js extension. However, in the last versions of Expo SDK everything should work well out of the box. What Expo SDK version are you using?
Also, you have to run the script after each yarn add or npm install, bc we change code in node_modules. You can add something like that to your package.json - "postinstall": "node ./scripts/fix-for-rn-rnw.js". And be sure to use fix-for-rn-rnw.js script.

@anil1712
Copy link

anil1712 commented May 9, 2021

Hi, Is there any solution for this? I am also getting the same

@mariomurrent-softwaresolutions

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.

Did you already solve this?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests