Getting web (and webpack) working with previous Expo project

Trying to follow this guide

I’m on expo 36.

We’ve been on expo for a long time, a few years, and we don’t even have a AppRegistry line in our app nor a index.js in our app. Here is the upgrade instructions for getting to expo web -

React Native-Only : Update your root index.js

  import {
      AppRegistry,
+      Platform
  } from 'react-native';
  import App from './App';
  import {name as appName} from './app.json';

  AppRegistry.registerComponent(appName, () => App);

+  if (Platform.OS === 'web') {
+      AppRegistry.runApplication(appName, {
+          rootTag: document.getElementById('root'),
+      });
+  }

So I’ve added an index.js which has all of the elements here, I’ve added the following to App.json:

     "entryPoint": "node_modules/expo/AppEntry.js",
...
    "platforms": [
      "android",
      "ios",
      "web"
    ]
  }

in package.json we’ve already got:

  "main": "./node_modules/expo/AppEntry.js",

I had to put a flag on Mobile only features, then I needed to override the default webpack loader with a typescript loader, the error I’m getting on expo start --web seems to be a react-native error:

 web  Failed to compile.
./node_modules/react-native/Libraries/react-native/react-native-implementation.js
Module not found: Can't resolve '../Components/AccessibilityInfo/AccessibilityInfo' in '/home/user/WebstormProjects/myApp/customer/node_modules/react-native/Libraries/react-native'
✖ 「wdm」: Hash: c932c15ca702129a5e96
Version: webpack 4.39.0
Time: 668ms
Built at: 12/11/2019 5:56:10 PM
  Asset      Size  Chunks  Chunk Names
main.js  41.8 KiB       0  main
Entrypoint main = main.js
 [0] ./node_modules/react-native/Libraries/react-native/react-native-implementation.js 15.3 KiB {0} [built]
 [1] ./app.json 1.36 KiB {0} [built]
 [2] ./node_modules/react-native/Libraries/Renderer/shims/ReactNative.js 334 bytes {0} [built] [failed] [1 error]
 [3] ./node_modules/react-native/Libraries/EventEmitter/RCTDeviceEventEmitter.js 464 bytes {0} [built] [failed] [1 error]
 [5] ./App.js 444 bytes {0} [built] [failed] [1 error]
 [6] ./index.js 296 bytes {0} [built]
 [7] ./node_modules/invariant/browser.js 1.36 KiB {0} [built]
 [8] ./node_modules/react-native/Libraries/Utilities/warnOnce.js 339 bytes {0} [built] [failed] [1 error]
 [9] ./node_modules/react-native/Libraries/Components/ActivityIndicator/ActivityIndicator.js 409 bytes {0} [built] [failed] [1 error]
[10] ./node_modules/react-native/Libraries/ART/ReactNativeART.js 355 bytes {0} [built] [failed] [1 error]
[11] ./node_modules/react-native/Libraries/Components/Button.js 375 bytes {0} [built] [failed] [1 error]
[12] ./node_modules/react-native/Libraries/Lists/FlatList.js 381 bytes {0} [built] [failed] [1 error]
[13] ./node_modules/react-native/Libraries/Image/ImageBackground.js 378 bytes {0} [built] [failed] [1 error]
[14] ./node_modules/react-native/Libraries/Components/TextInput/InputAccessoryView.js 405 bytes {0} [built] [failed] [1 error]
[15] ./node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js 442 bytes {0} [built] [failed] [1 error]
    + 63 hidden modules

WARNING in ./index.js 5:30-37
"export 'name' (imported as 'appName') was not found in './app.json'

WARNING in ./index.js 8:29-36
"export 'name' (imported as 'appName') was not found in './app.json'

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.

I’m kind of at a loss as to what to do next. Any suggestions?

What I would try is create a new bare typescript app using expo init. Then compare the newly generated files (app.json, package.json, App.tsx, babel.config.js, tsconfig.json) with the corresponding files in your app.

If you need a customized webpack config then also run expo customize:web in the blank project.

Hi everyone,

Also like @mgt I have a mature expo managed project (started on SDK 31) that is currently running SDK 36 perfectly on both android and ios. Product lifecycle now claims for a web version and while following the setup to integrate the web platform to our expo.platforms array on app.json was seamless (thanks to the great docs! :heart:), I got this error when compiling it for the web. Please note that it is slightly different from the one that the thread author posted, but follows within the same category:

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

Looking into node_modules/react_native folder, I saw that indeed the node_modules/react-native/Libraries/Utilities/Platform.js doesn’t exist, but it has Platform.android.js and Platform.ios.js.

So when I read @wodin suggestion, I tried to spin up a brand new CRNA managed project hoping to see what those node_modules/react-native files looked like on a web build that could successfully compile so I maybe could figure out which react-native/platform file to use (fixed with patch-package or something else), but ended up having another unrelated issue that also has an open thread here at expo forums:slightly_frowning_face:

All help and/or insight into any of these issues would be greatly appreciated. Thanks in advance!

Hi. hmmm… I am not sure why I said “bare”. I think I just mean a new “blank” app.

Anyway, I would create a new app with expo init and make sure that compiles. Then compare the app.json and package.json and other config/code. You could try making changes to the old app to make it more similar to the new one. If that doesn’t help, you could try clearing out your node_modules and re-installing them. Also maybe remove yarn.lock or package-lock.json before reinstalling deps.

If that doesn’t work, start copying code from the old app to the new one bit by bit and make sure at each step it still compiles. If it stops compiling then narrow down what caused it to break and post about it here. Hopefully someone will be able to work out what’s wrong.

1 Like

Thanks for the next set of suggested steps to try out.

I created new projects with expo init and they compile successfully to web in both blank and tab templates. Here are my findings so far on both fresh expo init project and my mature project:

Blank expo init project

It gets interesting when I change the blank template App.js file from this:

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Open up App.js to start working on your app!</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

to this:

import React from 'react';
import { StyleSheet, TextInput, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <TextInput />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Then, when I try to run it again with expo start --web, the __fbBatchedBridgeConfig is not set error gets thrown. This is a runtime error because expo build:web works, so compilation should be fine. Got stuck on this route.


Mature SDK36 App

In an attempt to stabilize the web compilation errors, I also tried to run expo build:web on my project. Remember that it was throwing Cannot resolve '../../Utilities/Platform' in './node_modules/react-native/Libraries/Components/TextInput' when ran with expo start --web? Well, if I try to build with expo build:web I get a different error, but also related to a react-native core package: AsyncStorage

➜$ 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)

Our project uses AsyncStorage in the persistor config for our redux state, but for the sake of experimentation, I commented out all references to it on our code, and gave it another spin:

➜$ EXPO_DEBUG=true expo build:web

● Expo Webpack █████████████████████████ building (24%) 119/150 modules 31 active
 babel-loader › node_modules/expo-asset/build/ImageAssets.js

 web  Failed to compile.

Module not found: Error: Can't resolve 'react-native-web/dist/exports/AsyncStorage' in './node_modules/expo/build/Notifications'
Error: Module not found: Error: Can't resolve 'react-native-web/dist/exports/AsyncStorage' in './node_modules/expo/build/Notifications'
    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)

Since the project also uses expo notifications module and it seems that expo uses AsyncStorage internally on that package, I got stuck on this route as well.


P.S.: As a final note, I would like to point out that it gets even more interesting when I looked into the node_modules/react-native TextInput files of expo init successful web builds. They are exactly the same on as they are on my SDK36 project, where TextInputState.js imports Platform from '../../Utilities/Platform'and that file doesn’t exist.

TLDR: All of these findings bring me to one question @wodin: Are react-native core modules (such as TextInput and AsyncStorage) supported by expo web platform?

This is really weird. If I expo init a new blank project and replace the Text component with a TextInput component, expo start --web works for me, as does expo build:web. The TextInput is invisible by default because it has no border/shadow/etc. so I added a border so that I could see it. I got no errors and it displayed fine when served from the Expo dev server or from the web-build directory using python -mSimpleHTTPServer.

What version of expo-cli do you have installed? Try running expo diagnostics inside the blank app and post the output. I upgraded to 3.18.0 just before the above test.

AsyncStorage should also work as far as I know.

1 Like

Got a bit of progress on this issue. For all my previous reports, I was using expo-cli on 3.17.24 and today, when suggested to try out 3.18.0 instead, I gave that a shot and it worked for the blank app! But I started from scratch, deleting the folder created by 3.17.24, running expo init again and including the TextInput component on App.js. I can now see a web version of react-native TextInput.

But there is a caveat… I rolled back to the previous cli version by running npm install -g expo-cli@3.17.24 just to see if I could repro the __fbBatchedBridgeConfig is not set error consistently and I could not! TextInput on web worked just fine in the expo init blank app for 3.17.24 after installing 3.18.0

For what its worth, here goes the expo diagnostics output for the blank project on both cli versions:

  Expo CLI 3.17.24 environment info:
    System:
      OS: macOS 10.15.3
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 13.8.0 - ~/.nvm/versions/node/v13.8.0/bin/node
      Yarn: 1.22.0 - /usr/local/bin/yarn
      npm: 6.13.6 - ~/.nvm/versions/node/v13.8.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.5 AI-191.8026.42.35.6010548
      Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
    npmPackages:
      expo: ~37.0.3 => 37.0.7 
      react: ~16.9.0 => 16.9.0 
      react-native: https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz => 0.61.4 
    npmGlobalPackages:
      expo-cli: 3.17.24

  Expo CLI 3.18.0 environment info:
    System:
      OS: macOS 10.15.3
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 13.8.0 - ~/.nvm/versions/node/v13.8.0/bin/node
      Yarn: 1.22.0 - /usr/local/bin/yarn
      npm: 6.13.6 - ~/.nvm/versions/node/v13.8.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.5 AI-191.8026.42.35.6010548
      Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
    npmPackages:
      expo: ~37.0.3 => 37.0.7 
      react: ~16.9.0 => 16.9.0 
      react-native: https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz => 0.61.4 
    npmGlobalPackages:
      expo-cli: 3.18.0

Going back to my SDK36 project, when I tried web compilation with 3.18.0 expo-cli, it gave me the same errors (expo start:web throwing TextInputState.js error and expo build:web throwing AsyncStorage error), so the errors for this project are consistent between 3.17.24 and 3.18.0. Expo diagnostics on this project are:

  Expo CLI 3.18.0 environment info:
    System:
      OS: macOS 10.15.3
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 13.8.0 - ~/.nvm/versions/node/v13.8.0/bin/node
      Yarn: 1.22.0 - /usr/local/bin/yarn
      npm: 6.13.6 - ~/.nvm/versions/node/v13.8.0/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.5 AI-191.8026.42.35.6010548
      Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
    npmPackages:
      expo: ^36.0.2 => 36.0.2 
      react: 16.9.0 => 16.9.0 
      react-native: https://github.com/expo/react-native/archive/sdk-36.0.1.tar.gz => 0.61.4 
      react-navigation: 4.3.7 => 4.3.7 
    npmGlobalPackages:
      expo-cli: 3.18.0

Please note that between each web compilation I did for these projects, I ran:

  • For the blank projects:
    • rm -rf on the existing folder
    • bootstrapped a new blank project with expo init,
  • For the SDK36 project:
    • rm -rf .expo to clear web build cache
    • rm -rf web-build to clear web build assets
    • rm -rf package-lock.json to release dependency locks
    • rm -rf node_modules && npm cache clean --force && npm i to have fresh project dependencies

Since the blank project now works with TextInput, at least I have the route of “copying small code chunks from the old project to the blank project and compiling to web at each step” to try. I’ll keep posting my findings here. Thanks for all the help @wodin!

1 Like

This issue is still open : https://github.com/expo/web-examples/issues/73
We need a clear process to solve this, otherwise it’s impossible to promote react-native-web as stable enough for projects. I’m stuck since months now, hoping that this would be solved in a reasonable amount of time and effort. But it’s not, more and more developers fall into this trap, please solve this asap.

expo diagnostics

  Expo CLI 3.22.3 environment info:
    System:
      OS: macOS 10.15.6
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 12.13.1 - /usr/local/bin/node
      Yarn: 1.22.4 - /usr/local/bin/yarn
      npm: 3.10.10 - /usr/local/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    IDEs:
      Android Studio: 3.4 AI-183.6156.11.34.5692245
      Xcode: 11.6/11E708 - /usr/bin/xcodebuild
    npmGlobalPackages:
      expo-cli: 3.22.3
 web  Failed to compile.
/xxxx/react-native/Libraries/Components/TextInput/TextInputState.js
Module not found: Can't resolve '../../Utilities/Platform' in '/xxxx/node_modules/react-native/Libraries/Components/TextInput'
1 Like