stripe-react-native icon indicating copy to clipboard operation
stripe-react-native copied to clipboard

Expo managed workflow - crash on web

Open nzhenry opened this issue 3 years ago • 33 comments

Describe the bug Importing dependencies from @stripe/stripe-react-native causes app to crash on Expo managed workflow - web.

To Reproduce Steps to reproduce the behavior:

  1. Create new expo managed workflow project
  2. expo install @stripe/stripe-react-native
  3. import stripe dependencies into component
  4. expo start --web
  5. See errors

Expected behavior No errors unless stripe components are actually used at runtime.

Additional context I'm aware that web isn't supported, but it would be nice if it would at least build so I could run my app. I don't plan to render any stripe components in the browser at runtime. Currently I can't figure out a way to make Webpack exclude this dependency. Any help would be greatly appreciated.

nzhenry avatar May 02 '22 10:05 nzhenry

See errors

What are the errors? Please share a github repo that we can use to test this

charliecruzan-stripe avatar May 04 '22 19:05 charliecruzan-stripe

ERROR
08:03
./node_modules/react-native/Libraries/Components/TextInput/TextInputState.js:18:17
Module not found: Can't resolve '../../Utilities/Platform'
  16 | 
  17 | const React = require('react');
> 18 | const Platform = require('../../Utilities/Platform');
     |                 ^
  19 | const {findNodeHandle} = require('../../Renderer/shims/ReactNative');
  20 | import {Commands as AndroidTextInputCommands} from '../../Components/TextInput/AndroidTextInputNativeComponent';
  21 | import {Commands as iOSTextInputCommands} from '../../Components/TextInput/RCTSingelineTextInputNativeComponent';
ERROR
08:03
./node_modules/react-native/Libraries/Core/Timers/JSTimers.js:14:17
Module not found: Can't resolve '../../Utilities/Platform'
  12 | 
  13 | const BatchedBridge = require('../../BatchedBridge/BatchedBridge');
> 14 | const Platform = require('../../Utilities/Platform');
     |                 ^
  15 | const Systrace = require('../../Performance/Systrace');
  16 | 
  17 | const invariant = require('invariant');
ERROR
08:03
./node_modules/@stripe/stripe-react-native/lib/module/components/StripeProvider.js:1:515
Module not found: Can't resolve '../../package.json'
> 1 | var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.StripeProvider=StripeProvider;exports.initStripe=void 0;var _regenerator=_interopRequireDefault(require("@babel/runtime/regenerator"));var _defineProperty2=_interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));var _react=require("react");var _NativeStripeSdk=_interopRequireDefault(require("../NativeStripeSdk"));var _helpers=require("../helpers");var _package=_interopRequireDefault(require("../../package.json"));function ownKeys(object,enumerableOnly){var keys=Object.keys(object);if(Object.getOwnPropertySymbols){var symbols=Object.getOwnPropertySymbols(object);if(enumerableOnly){symbols=symbols.filter(function(sym){return Object.getOwnPropertyDescriptor(object,sym).enumerable;});}keys.push.apply(keys,symbols);}return keys;}function _objectSpread(target){for(var i=1;i<arguments.length;i++){var source=arguments[i]!=null?arguments[i]:{};if(i%2){ownKeys(Object(source),true).forEach(function(key){(0,_defineProperty2.default)(target,key,source[key]);});}else if(Object.getOwnPropertyDescriptors){Object.defineProperties(target,Object.getOwnPropertyDescriptors(source));}else{ownKeys(Object(source)).forEach(function(key){Object.defineProperty(target,key,Object.getOwnPropertyDescriptor(source,key));});}}return target;}var EXPO_PARTNER_ID='pp_partner_JBN7LkABco2yUu';var repository=_package.default.repository;var appInfo={name:(0,_helpers.shouldAttributeExpo)()?_package.default.name+"/expo":_package.default.name,url:repository.url||repository,version:_package.default.version,partnerId:(0,_helpers.shouldAttributeExpo)()?EXPO_PARTNER_ID:undefined};var initStripe=function initStripe(params){var extendedParams;return _regenerator.default.async(function initStripe$(_context){while(1){switch(_context.prev=_context.next){case 0:extendedParams=_objectSpread(_objectSpread({},params),{},{appInfo:appInfo});_NativeStripeSdk.default.initialise(extendedParams);case 2:case"end":return _context.stop();}}},null,null,null,Promise);};exports.initStripe=initStripe;function StripeProvider(_ref){var children=_ref.children,publishableKey=_ref.publishableKey,merchantIdentifier=_ref.merchantIdentifier,threeDSecureParams=_ref.threeDSecureParams,stripeAccountId=_ref.stripeAccountId,urlScheme=_ref.urlScheme,setUrlSchemeOnAndroid=_ref.setUrlSchemeOnAndroid;(0,_react.useEffect)(function(){if(!publishableKey){return;}if(_helpers.isAndroid){_NativeStripeSdk.default.initialise({publishableKey:publishableKey,appInfo:appInfo,stripeAccountId:stripeAccountId,threeDSecureParams:threeDSecureParams,urlScheme:urlScheme,setUrlSchemeOnAndroid:setUrlSchemeOnAndroid});}else{_NativeStripeSdk.default.initialise({publishableKey:publishableKey,appInfo:appInfo,stripeAccountId:stripeAccountId,threeDSecureParams:threeDSecureParams,merchantIdentifier:merchantIdentifier,urlScheme:urlScheme});}},[publishableKey,merchantIdentifier,stripeAccountId,threeDSecureParams,urlScheme,setUrlSchemeOnAndroid]);return children;}
    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   ^
  2 | //# sourceMappingURL=StripeProvider.js.map
ERROR
08:03
./node_modules/react-native/Libraries/Alert/Alert.js:13
Module not found: Can't resolve '../Utilities/Platform'
  11 | 'use strict';
  12 | 
> 13 | import Platform from '../Utilities/Platform';
  14 | import NativeDialogManagerAndroid, {
  15 |   type DialogOptions,
  16 | } from '../NativeModules/specs/NativeDialogManagerAndroid';
ERROR
08:03
./node_modules/react-native/Libraries/Core/NativeExceptionsManager.js:60:17
Module not found: Can't resolve '../Utilities/Platform'
  58 | }
  59 | 
> 60 | const Platform = require('../Utilities/Platform');
     |                 ^
  61 | 
  62 | const NativeModule = TurboModuleRegistry.getEnforcing<Spec>(
  63 |   'ExceptionsManager',
ERROR
08:03
./node_modules/react-native/Libraries/Core/setUpDeveloperTools.js:13
Module not found: Can't resolve '../Utilities/Platform'
  11 | 'use strict';
  12 | 
> 13 | import Platform from '../Utilities/Platform';
  14 | 
  15 | declare var console: typeof console & {_isPolyfilled: boolean, ...};
  16 | 
ERROR
08:03
./node_modules/react-native/Libraries/Core/ReactNativeVersionCheck.js:13
Module not found: Can't resolve '../Utilities/Platform'
  11 | 'use strict';
  12 | 
> 13 | import Platform from '../Utilities/Platform';
  14 | const ReactNativeVersion = require('./ReactNativeVersion');
  15 | 
  16 | /**
ERROR
08:03
./node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js:13
Module not found: Can't resolve '../Utilities/Platform'
  11 | 'use strict';
  12 | 
> 13 | import Platform from '../Utilities/Platform';
  14 | import EventEmitter from '../vendor/emitter/EventEmitter';
  15 | import {type EventSubscription} from '../vendor/emitter/EventEmitter';
  16 | import RCTDeviceEventEmitter from './RCTDeviceEventEmitter';
ERROR
08:03
./node_modules/react-native/Libraries/Image/AssetSourceResolver.js:24:17
Module not found: Can't resolve '../Utilities/Platform'
  22 | 
  23 | const PixelRatio = require('../Utilities/PixelRatio');
> 24 | const Platform = require('../Utilities/Platform');
     |                 ^
  25 | 
  26 | const invariant = require('invariant');
  27 | 
ERROR
08:03
./node_modules/react-native/Libraries/ReactNative/PaperUIManager.js:14:17
Module not found: Can't resolve '../Utilities/Platform'
  12 | 
  13 | const NativeModules = require('../BatchedBridge/NativeModules');
> 14 | const Platform = require('../Utilities/Platform');
     |                 ^
  15 | const UIManagerProperties = require('./UIManagerProperties');
  16 | 
  17 | const defineLazyObjectProperty = require('../Utilities/defineLazyObjectProperty');
ERROR
08:03
./node_modules/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js:32:11
Module not found: Can't resolve '../Utilities/Platform'
  30 |   },
  31 |   get Platform(): Platform {
> 32 |     return require('../Utilities/Platform');
     |           ^
  33 |   },
  34 |   get RCTEventEmitter(): RCTEventEmitter {
  35 |     return require('../EventEmitter/RCTEventEmitter');
ERROR
08:03
./node_modules/react-native/Libraries/StyleSheet/processColor.js:13:17
Module not found: Can't resolve '../Utilities/Platform'
  11 | 'use strict';
  12 | 
> 13 | const Platform = require('../Utilities/Platform');
     |                 ^
  14 | 
  15 | const normalizeColor = require('./normalizeColor');
  16 | 
ERROR
08:03
./node_modules/react-native/Libraries/StyleSheet/processTransform.js:14:17
Module not found: Can't resolve '../Utilities/Platform'
  12 | 
  13 | const MatrixMath = require('../Utilities/MatrixMath');
> 14 | const Platform = require('../Utilities/Platform');
     |                 ^
  15 | 
  16 | const invariant = require('invariant');
  17 | const stringifySafe = require('../Utilities/stringifySafe').default;
ERROR
08:03
./node_modules/react-native/Libraries/Utilities/HMRClient.js:16:17
Module not found: Can't resolve './Platform'
  14 | const invariant = require('invariant');
  15 | const MetroHMRClient = require('metro-runtime/src/modules/HMRClient');
> 16 | const Platform = require('./Platform');
     |                 ^
  17 | const prettyFormat = require('pretty-format');
  18 | 
  19 | import getDevServer from '../Core/Devtools/getDevServer';
ERROR
08:03
./node_modules/react-native/Libraries/StyleSheet/processColor.js:34:31
Module not found: Can't resolve './PlatformColorValueTypes'
  32 | 
  33 |   if (typeof normalizedColor === 'object') {
> 34 |     const processColorObject = require('./PlatformColorValueTypes')
     |                               ^
  35 |       .processColorObject;
  36 | 
  37 |     const processedColorObj = processColorObject(normalizedColor);
ERROR
08:03
./node_modules/react-native/Libraries/StyleSheet/normalizeColor.js:24:35
Module not found: Can't resolve './PlatformColorValueTypes'
  22 | ): ?ProcessedColorValue {
  23 |   if (typeof color === 'object' && color != null) {
> 24 |     const {normalizeColorObject} = require('./PlatformColorValueTypes');
     |                                   ^
  25 |     const normalizedColor = normalizeColorObject(color);
  26 |     if (normalizedColor != null) {
  27 |       return color;
ERROR
08:03
./node_modules/react-native/Libraries/Alert/Alert.js:17
Module not found: Can't resolve './RCTAlertManager'
  15 |   type DialogOptions,
  16 | } from '../NativeModules/specs/NativeDialogManagerAndroid';
> 17 | import RCTAlertManager from './RCTAlertManager';
  18 | 
  19 | export type AlertType =
  20 |   | 'default'
ERROR
08:03
./node_modules/react-native/Libraries/Network/XMLHttpRequest.js:18:22
Module not found: Can't resolve './RCTNetworking'
  16 | const EventTarget = require('event-target-shim');
  17 | const GlobalPerformanceLogger = require('../Utilities/GlobalPerformanceLogger');
> 18 | const RCTNetworking = require('./RCTNetworking');
     |                      ^
  19 | 
  20 | const base64 = require('base64-js');
  21 | const invariant = require('invariant');

nzhenry avatar May 04 '22 20:05 nzhenry

Here's a sample repo https://github.com/nzhenry/stripe-expo-web-sample

nzhenry avatar May 04 '22 20:05 nzhenry

There seem to be other errors besides stripe-react-native, are those expected for you?

charliecruzan-stripe avatar May 04 '22 20:05 charliecruzan-stripe

No. All the errors were introduced when I added the Stripe library.

nzhenry avatar May 04 '22 20:05 nzhenry

Gotchya, we probably just need to stub out almost-empty .web files

charliecruzan-stripe avatar May 04 '22 20:05 charliecruzan-stripe

I've just ran into the same issue, would be nice to see those stubbing web files added :)

olaurendeau avatar May 19 '22 19:05 olaurendeau

@olaurendeau I have a workaround for now. I've implemented separate application entry points for mobile and web, with a basic dependency injection container to abstract away the platform dependent components. It's not ideal, but it works.

nzhenry avatar May 19 '22 19:05 nzhenry

I'm facing only this error:

Module not found: Can't resolve './RCTNetworking'
  16 | const EventTarget = require('event-target-shim');
  17 | const GlobalPerformanceLogger = require('../Utilities/GlobalPerformanceLogger');
> 18 | const RCTNetworking = require('./RCTNetworking');
     |                      ^
  19 |
  20 | const base64 = require('base64-js');
  21 | const invariant = require('invariant');

anabeatrizzz avatar Jun 14 '22 22:06 anabeatrizzz

@olaurendeau, hello thank you for the suggestion! If you have time, can you explain more about the dependency injection container to abstract away the platform dependent components ?

ebo7 avatar Sep 28 '22 15:09 ebo7

https://github.com/stripe/stripe-react-native/issues/917#issuecomment-1117838001

Hi Any Ideas to solve the question? I facing this problem too

FelixChong980212 avatar Oct 06 '22 11:10 FelixChong980212

I am still working through the first web build of my app but I seem to have got round this particular error for the meantime by adding null-loader as an alias for @stripe/stripe-react-native in my webpack config.

I added a webpack.config.js as described here and then modified it so it looks like this excerpt. I also installed the null-loader package.

webpack.config.js

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

module.exports = async function (env, argv) {
  const config = await createExpoWebpackConfigAsync(env, argv);
  config.resolve.alias["@stripe/stripe-react-native"] = "null-loader";
  return config;
};

robert-nash avatar Oct 25 '22 09:10 robert-nash

Let me make the steps explicit for the lazy folks like future me. (All credits to @robert-nash , in his previous answer.)

  1. Add null-loader

    yarn add -D null-loader
    
  2. Generate the webpack.config.js file with expo's template:

    npx expo customize webpack.config.js
    
  3. Modify webpack.config.js, add the line marked with the comment ADD THIS LINE. Final version of the file should look like:

    // 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.resolve.alias["@stripe/stripe-react-native"] = "null-loader"; // ADD THIS LINE
    	return config;
    };
    

MehmetKaplan avatar Feb 20 '23 20:02 MehmetKaplan

Facing this issue too, the fix posted by @robert-nash / @MehmetKaplan is not working for me.

RobertMercieca avatar Aug 29 '23 19:08 RobertMercieca

I'm also having this issue.

JorensM avatar Sep 01 '23 07:09 JorensM

facing same error

gunwant11 avatar Sep 07 '23 14:09 gunwant11

For me this was caused by lottie-react-native.

markedwards avatar Sep 12 '23 17:09 markedwards

facing same issue.The fixes above are not working for me. Anybody else have any ideas how to resolve this issue?

malusiTowo avatar Oct 18 '23 14:10 malusiTowo

I'm facing only this error:

Module not found: Can't resolve './RCTNetworking'
  16 | const EventTarget = require('event-target-shim');
  17 | const GlobalPerformanceLogger = require('../Utilities/GlobalPerformanceLogger');
> 18 | const RCTNetworking = require('./RCTNetworking');
     |                      ^
  19 |
  20 | const base64 = require('base64-js');
  21 | const invariant = require('invariant');

Did you fix it mate ?

kynectionjerry avatar Oct 23 '23 08:10 kynectionjerry

I'm facing only this error:

Module not found: Can't resolve './RCTNetworking'
  16 | const EventTarget = require('event-target-shim');
  17 | const GlobalPerformanceLogger = require('../Utilities/GlobalPerformanceLogger');
> 18 | const RCTNetworking = require('./RCTNetworking');
     |                      ^
  19 |
  20 | const base64 = require('base64-js');
  21 | const invariant = require('invariant');

Did you fix it mate ?

@anabeatrizzz

kynectionjerry avatar Oct 23 '23 08:10 kynectionjerry

hey guyzz for the stripe issue you can initially add null loader like this to resolve the TextInputState Error here is my webpackConfig.js file for adding alias Screenshot from 2023-11-27 17-36-09 and create a separate NullModuleloader file like this Screenshot from 2023-11-27 17-37-11

mubeen1519 avatar Nov 27 '23 12:11 mubeen1519

I managed to solve this by using Platform extensions. I created a file stripe.ts for web which exports placeholder components/functions, and created a file stripe.native.ts for mobile which exports the actual stripe components/functions. Now I can import by ./stripe and it will automatically import the correct module based on which platform I'm using.

JorensM avatar Jan 17 '24 11:01 JorensM