Capacitor: Issue in IE11 when importing plugins from @capacitor/core

Created on 12 Apr 2018  路  16Comments  路  Source: ionic-team/capacitor

The following produces an error in IE11 about proxy not being defined:

import { Plugins } from '@capacitor/core'
const { Device } = Plugins
console.log(Device)

The error message in the console in my swedish IE11 says: "Proxy har inte definierats" (Proxy has not been defined).

Will this be fixed?

low

Most helpful comment

I responded in another issue, but we're strongly leaning towards not supporting IE 11. By supporting it, we'll have to invest time on IE 11 instead of making Capacitor better for all the other platforms we support. Also, IE 11 does not support any PWA APIs.

Various stats show IE 11 usage at < 3% worldwide, and once we get into production ready status that number should drop even more.

It's time to move on.

All 16 comments

I responded in another issue, but we're strongly leaning towards not supporting IE 11. By supporting it, we'll have to invest time on IE 11 instead of making Capacitor better for all the other platforms we support. Also, IE 11 does not support any PWA APIs.

Various stats show IE 11 usage at < 3% worldwide, and once we get into production ready status that number should drop even more.

It's time to move on.

I agree with your decision and find it very sound. Do you have any suggestion how to condition the import so it occurs only if not on IE11? I want the application to work on IE11 even if it is without the plugins from Capacitor. I played around with "require" instead of using "import". It will compile but the check won't in that case work on my apps for some reason. If you have any thoughts to guide me in the right direction that would be appreciated.

My check:

async function getDeviceInfo () {
      try {
        let response = await Device.getInfo()
        return response
      } catch (err) {
        console.log(err)
      }
    }
    getDeviceInfo().then((device) => {
      if (device.platform !== 'web') {
        this.isMobile = true
      }
    })

The field "isMobile" will then be used to show/hide some HTML-elements. All this works fine when using the import-statement:

import { Plugins } from '@capacitor/core'
const { Device } = Plugins

But as I said. Then the application won't start in IE11 at all.

According to the below link the windows 10 webview is powered by edge so capacitor should still have full support for hybrid apps on the windows universal apps without any need to support IE11.

https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.WebView

What would I need to do to fix this problem? Could you give me a hint?

Angular supports IE 9 - 11 and beside Capacitor my Angular apps runs - ok - with IE11 and although I share your opinion on IE but especially in non IT companies not using IE 11 this is easier said than done.

Some are still on Win7 and IE 11 is the default browser there.

I was able to conditionally require capacitor's Geolocation plugin as follows:

let Geolocation;
if (window.Proxy) {
  const capacitor = require('@capacitor/core');
  Geolocation = capacitor.Plugins.Geolocation;
}

And use HTML5 Geolocation otherwise.

I tried to use a polyfill for Proxy

npm i proxy-polyfill --save

and add it to polyfill.ts

import 'proxy-polyfill';

and add

"paths": {
      "proxy-polyfill": ["../node_modules/proxy-polyfill/proxy.min.js"]
}

to tsconfig.json so the es5 version of the polyfill is imported

So the polyfill errors is gone but it does not work either.

Is it possible that because Capacitor targets es2015 instead of es5 in tsconfig any approach will fail to solve this.

Angular uses in tsconfig

"compilerOptions": {
 "target": "es5",
}

Capacitory on the other hand uses in tsconfig

"compilerOptions": {
 "target": "es2015",
}

Is it possible for Capacitor to target es5 as well?

thx

My issue #1340 as is not depend on Android version, but depend on WebView version. I cannot force/suggest on every user that want use my app to update their WebView.
@moberwasserlechner are you success to use polyfill for proxy?

@taufikterdidik It didn't work with polyfills.

I then decided that IE11 is not that important and hopefully since MS will end support for Win7 in 2020 the problem will solve itself. At least some government users will be forced to using a proper browser.

I wanted to render a version that doesn't use Capacitor in IE11.

Building on what @uturnr said above, I import Capacitor via my own module:

//capacitor.ts
export let Capacitor;
export let Plugins;
try {
    if (window.Proxy) {
        const capacitor = require('@capacitor/core');
        Capacitor = capacitor.Capacitor;
        Plugins = capacitor.Plugins;
    } else {

        Capacitor = undefined;
        Plugins = undefined;
    }
}
catch (e) {
    // Catch the error IE11 throws about Proxy being undefied;
}

Then I can import Capacitor and Plugins like this:

import { Capacitor, Plugins } from "./capacitor";

Same here, tried to open my web-app on an iOS 9 iPad and Android 4 Tablet, both failed due to this.

We ran into this problem as well when we had to support IE11 when running our SPA via web browser.

Since our application does not require any Capacitor features while running in the browser we solved the issue by building two bundles: one that contains the Capacitor bindings (App scenario) and one without them (web scenario).

We did this by adding the ifdef-loader to webpack and then wrapped the Capacitor specific code into conditional compilation directives.

// only include this dependencies if we are building for capacitor
/// #if APP_MODE
import { Plugins } from '@capacitor/core';
const { SplashScreen } = Plugins;
/// #endif

I responded in another issue, but we're strongly leaning towards not supporting IE 11. By supporting it, we'll have to invest time on IE 11 instead of making Capacitor better for all the other platforms we support.

I think there's a difference between not supporting IE11, and actively breaking it. Unfortunately Proxy is one of those rare JavaScript API that can't be polyfilled on older engines. For instance, the only viable polyfill requires you to know the properties you want to proxy at creation time, which is effectively the same as defining lots of Object property getters, and can't be used in Capacitor's case.

Also, IE 11 does not support any PWA APIs.

IMO PWAs are more than a set of APIs: the "Progressive" part means that the web apps get progressively better on newer engines, yet still work across all devices, as per the first sentence from Google's PWA checklist:

Progressive Web Apps (PWA) are built and enhanced with modern APIs to deliver native-like capabilities, reliability, and installability while reaching anyone, anywhere, on any device with a single codebase.

The "Works in any browser" part is re-stated as item #2 in that same checklist.

Various stats show IE 11 usage at < 3% worldwide, and once we get into production ready status that number should drop even more.
It's time to move on.

As much as I'd love to agree with you, the sad reality is that those few percents often include the most valuable consumers for many businesses, as a large part of fortune 500s are still running IE11, often because they also have to support legacy IE11-only web apps in parallel.

Don't get me wrong: we all hate IE11 here, but unfortunately most of us don't have the luxury of just ignoring it.

I was able to conditionally require capacitor's Geolocation plugin as follows

The issue with using a conditional import is that it works until it doesn't: I was doing the same trick, until Webpack code-splitting algorithm saw that that import are required from multiple places, and decided to optimize it by inlining the code into the main app bundle, effectively silently breaking IE11.

In addition, while on the surface Capacitor looks like a modern ES module-based library, the simple fact of importing Capacitor (import { Capacitor } from '@capacitor/core';) creates a counter-intuitive side-effect (effectively breaking tree-shacking) by instantiating CapacitorWeb & exposing it on the global object, which I'd argue is another problem in itself.

Anyway, since Capacitor's use of Proxy is limited to throwing a Promise rejection when trying to access an unavailable plugin, I'd argue that said use should just be guarded: it means that trying to access an unavailable plugin will throw in IE11 (instead of returning a Promise rejection), but at least Capacitor won't throw a global Syntax Error on import anymore (and not trying to use an unavailable plugin can be controlled on the caller side, i.e. by the user).

For what it's worth, @laurentgoudet's change #2759 made our pretty complex Capacitor application work fine on IE11.

Perhaps although Ionic's (perfectly reasonable) position is that Capacitor isn't supported on IE11, they'll accept community pull requests like this that don't affect the features on engines that are officially supported?

Would be very thankful for this PR to be merged as well!

We would be open to a PR that adds some guards to the use of the proxy as long as it doesn't diminish the experience for the other users.

Thanks for getting back @mlynch - this is what https://github.com/ionic-team/capacitor/pull/2759 does, let me know if it looks good to you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

json-derulo picture json-derulo  路  3Comments

mlynch picture mlynch  路  3Comments

natevw picture natevw  路  3Comments

nicobytes picture nicobytes  路  3Comments

stripathix picture stripathix  路  3Comments