Giter Club home page Giter Club logo

browser-polyfill's Introduction

@expo/browser-polyfill

Browser polyfill for React Native

Installation

yarn add @expo/browser-polyfill

Usage

Import the library into your JavaScript file:

import '@expo/browser-polyfill';

Implements

DOM

DOM is provided with very low support, these are used for libs like pixi.js that validate type.

class Node
class Element
class Document
class HTMLImageElement
class Image
class ImageBitmap
class HTMLVideoElement
class Video
class HTMLCanvasElement
class Canvas

Image, HTMLImageElement, ImageBitmap

Image has support for loading callbacks, however the loaded uri must be passed to the src already.

const image = new Image();
image.src = '';
image.onload = () => {
  const { src, width, height } = image;
};
image.addEventListener('loading', () => {});
image.addEventListener('error', () => {});

Document

const element = document.createElement('div');
const fakeContext = element.getContext('');

Element

All sizes return the window size:

element.clientWidth;
element.clientHeight;
element.innerWidth;
element.innerHeight;
element.offsetWidth;
element.offsetHeight;

Empty attributes that prevent libraries from crashing

element.tagName;
element.addEventListener;
element.removeEventListener;
element.setAttributeNS;
element.createElementNS;

Node

node.ownerDocument;
node.className;
node.appendChild;
node.insertBefore;
node.removeChild;
node.setAttributeNS;
node.getBoundingClientRect;

External Libraries

Some external node.js polyfills are added as well.

global.TextEncoder
global.TextDecoder
window.DOMParser
console.time(label);
console.timeEnd(label);
console.count(label);

Debug flags

For debugging base64 image transformations toggle:

global.__debug_browser_polyfill_image = true;

By default global.__debug_browser_polyfill_image is false.

browser-polyfill's People

Contributors

asday avatar dependabot[bot] avatar evanbacon avatar ide avatar lukmccall avatar mghawes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

browser-polyfill's Issues

Firebase JS SDK breaks when importing @expo/browser-polyfill

This happened some time ago:
expo/expo-three#53
#2

and comes back again! @EvanBacon

WTR

Basically, one need to:

  1. Import @expo/browser-polyfill somewhere deep in the jungle of packages
  2. sign in using Firebase JS SDK
  3. observe some Firestore entity using onSnapshot, then unsubscribe (gracefully)
  4. sign out

This way is a 100% repro, but I have seen other random cases when that happened during Firebase sign in session.

Libraries

"@expo/browser-polyfill": "^0.1.0",
"expo": "~37.0.3",
"firebase": "7.9.0",
Code snippet to reproduce
import '@expo/browser-polyfill';

import firebase from 'firebase/app';

import 'firebase/auth';
import 'firebase/firestore';

const validFirebaseConfig = {
/* ... */
};

export async function doFirebaseTest() {
    // Initialize Firebase App
    const instance = firebase.initializeApp(validFirebaseConfig);

    // Do a simple log in
    console.log('logging in...');
    if (!instance.auth().currentUser) {
        await instance.auth().signInWithEmailAndPassword('[email protected]', '123456');
    }

    const uid = instance.auth().currentUser?.uid;

    // IMPORTANT: Add onSnapshot observer on any Firestore entity
    // only with this it will break
    console.log('subscribing to the user in Firestore...');
    const unsub1 = instance.firestore().doc(`users/${uid}`).onSnapshot(snapshot => {
        console.log('Got the User!!!', snapshot.data());
    });

    // just wait a bit to avoid race conditions
    console.log('waiting for 2 seconds...');
    setTimeout(async () => {
        unsub1();

        console.log('logging out...');
        // HERE you will see crash on Android or error RedBox for iOS simulator / Android emulator
        await instance.auth().signOut(); 
    
        console.log('completed!!!');
    }, 2000)
}

Actual Result

iOS

Device – nothing bad happens that a user can see
Simulator:

No suitable URL request handler found for (null)

-[ABI37_0_0RCTNetworking networkTaskWithRequest:completionBlock:]
    ABI37_0_0RCTNetworking.mm:654
-[ABI37_0_0RCTImageLoader _loadURLRequest:progressBlock:completionBlock:]
__127-[ABI37_0_0RCTImageLoader _loadImageOrDataWithURLRequest:size:scale:resizeMode:progressBlock:partialLoadBlock:completionBlock:]_block_invoke.183
_dispatch_call_block_and_release
_dispatch_client_callout
_dispatch_lane_serial_drain
_dispatch_lane_invoke
_dispatch_workloop_worker_thread
_pthread_wqthread
start_wqthread

Screenshot

image

Android feels much worse about it

Device – crash/reload
Virtual Device – app hangs with the error:

abi37_0_0.com.facebook.react.bridge.ReadableNativeMap cannot be cast to java.lang.String
Screenshot

image

importing '@expo/browser-polyfill' gives NotSupportedError: Cannot set "location".

When importing this package I get this error:
NotSupportedError: Cannot set "location".

I originally thought it was an issue with expo-three but narrowed it down to this package instead.

Expo managed project, SDK "~48.0.18", building for iOS.

for some reason
throw new DOMException("Cannot set "location".", "NotSupportedError");
in @expo/metro-runtime/build/location/Location.native.js
is being triggered just by importing this package?

Command Failed error

C:\Users\user\Documents\PONS FILES\WORK\JONATHAN\UOB-SUMMIT\node_modules\@expo\browser-polyfill: Command failed.
Exit code: 2
Command: find ../ -name .babelrc -delete
Arguments:
Directory: C:\Users\user\Documents\PONS FILES\WORK\JONATHAN\UOB-SUMMIT\node_modules\@expo\browser-polyfill


im installing expo-pixi but imgetting thiis error

Environment

Error: Unable to resolve module uuidv1 from 'uuid/v1';

It looks like the import import uuidv1 from 'uuid/v1'; in browser-polyfill/src/DOM/HTMLImageElement.js at ln6 isn't valid or a dependency was left out of your package.json.

I've been looking through the different uuid modules available on npm and none of them seem to fill this dependency. Could you provide a link to the correct module or update your package.json?

Outdated/not maintained dependencies

Hi,
I got those 2 warnings when installing this package (through [email protected]):

warning expo-three > @expo/browser-polyfill > [email protected]: no longer maintained
warning expo-three > @expo/browser-polyfill > fbemitter > fbjs > [email protected]: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.

Is it possible to update the dependencies?

Repro:

npx create-expo-app MyApp
cd MyApp
npm i expo-three expo-gl three@"^0.145.0"

Bundling failure

Hello! I'm having some issues adding this polyfill to my app. We have an ejected Expo app that is using unimodules.

Steps to Reproduce:

npm install @expo/browser-polyfill --save

In my file:

import '@expo/browser-polyfill';

error: bundling failed: Error: Unable to resolve module expo from /Users/jwilliamson/Developer/QBMobile/node_modules/@expo/browser-polyfill/src/DOM/HTMLImageElement.js: Module expo does not exist in the Haste module map

This might be related to facebook/react-native#4968
To resolve try the following:

  1. Clear watchman watches: watchman watch-del-all.
  2. Delete the node_modules folder: rm -rf node_modules && npm install.
  3. Reset Metro Bundler cache: rm -rf /tmp/metro-bundler-cache-* or npm start -- --reset-cache.
  4. Remove haste cache: rm -rf /tmp/haste-map-react-native-packager-*.

Alpha.4 changes cause incompatibilities with PIXI

The change made here causes PIXI to determine that a GL view cannot be used in their util.isWebGLSupported function which breaks expo-pixi. The second argument in the function was ignored initially but is now assumed to be a context which in PIXI's case it is not. This issue makes expo-pixi unusable with this package past alpha.3. I have locked the resolution of this package at alpha.3 which seems to have fixed my issue but this is not a solution I would like to keep.

I would submit a PR to fix it myself but I don't feel like I have the experience with this package and the packages it supports to make sure a solution I come up with wouldn't break another project.

npm install failed on windows 10

I meet the error:
`find ../ -name .babelrc -delete

FIND: Parameter format not correct

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! @expo/[email protected] postinstall: find ../ -name .babelrc -delete
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the @expo/[email protected] postinstall script.`

I install it on mac successfully.
Seems command 'find ../ -name .babelrc -delete' is broken.

too many console.warn() messages from performance.js

It looks like the performance.js polyfill has its functions called often, and adb can't handle all the console.warn() statements.

Conditions:

  • running on connected android device via adb
  • RN on device settings: JS Dev Mode checked
  • using expo-three & expo-gl

inspect the adb logs via: adb logcat *:S ReactNative:V ReactNativeJS:V

A console.warn() is issued for each call to window.mark, .measure, .clearMarks, and .clearMeasures once every 2ms.
Although disabling YellowBox messages does hide them, adb still gets choked up and the app soon crashes.

Full disclosure: I'm running from WSL2 with adb executing on the W side and rn-cli on the L side. (please don't judge)

Could you do something other than a console?
thanks

Receiving error on android (com.facebook.react.bridge.ReadableNativeMap cannot be cast to java.lang.Strin)

I am currently working on a new cryptocurrency / chat mobile app using matrix sdk (https://github.com/matrix-org/matrix-js-sdk), and this fails for me on android, I receive the com.facebook.react.bridge.ReadableNativeMap cannot be cast to java.lang.String error.
screen shot 2018-08-23 at 4 43 10 pm

  • Also I'm not too sure if this works on iOS with matrix SDK, since I don't need the polyfills on iOS, I only need the polyfills on android

How to reproduce

  • make browser-pollyfill a dependancy, and import it into your project
  • start your project, and within a few seconds - minutes, an error will appear
  • Device: Moto G5
  • Operating system: Android 🤦‍♂️

Current Solution

Right now I have a file called polyfill.js and I import it only for android within App.js - contents of this file were taken from Node.js file in this library, credit goes to @EvanBacon

import { EventEmitter } from 'fbemitter';

class Document {
  constructor() {
    this.emitter = new EventEmitter();
    this.addEventListener = this.addEventListener.bind(this);
    this.removeEventListener = this.removeEventListener.bind(this);
    this._checkEmitter = this._checkEmitter.bind(this);
  }

  createElement(tagName) {
    return {};
  }

  _checkEmitter() {
    if (
      !this.emitter ||
      !(this.emitter.on || this.emitter.addEventListener || this.emitter.addListener)
    ) {
      this.emitter = new EventEmitter();
    }
  }

  addEventListener(eventName, listener) {
    this._checkEmitter();
    if (this.emitter.on) {
      this.emitter.on(eventName, listener);
    } else if (this.emitter.addEventListener) {
      this.emitter.addEventListener(eventName, listener);
    } else if (this.emitter.addListener) {
      this.emitter.addListener(eventName, listener);
    }
  }

  removeEventListener(eventName, listener) {
    this._checkEmitter();
    if (this.emitter.off) {
      this.emitter.off(eventName, listener);
    } else if (this.emitter.removeEventListener) {
      this.emitter.removeEventListener(eventName, listener);
    } else if (this.emitter.removeListener) {
      this.emitter.removeListener(eventName, listener);
    }
  }
}

window.document = window.document || new Document();

New version for SDK46

With Expo SDK46 being released, can we get a new version of browser-polyfill with the following package.json updates:

  • peerDependencies.react = ^18.0.0
  • peerDependencies.react-native = ^0.69.5
  • peerDependencies.expo-file-system = ^14.1.0

For my current project, this affects expo-three as a transitive dependency.

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.