Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stencil doesn't work in iOS Safari <= 10.3.1 (and possibly < 11) #1900

Closed
cmaas opened this issue Sep 27, 2019 · 19 comments
Closed

Stencil doesn't work in iOS Safari <= 10.3.1 (and possibly < 11) #1900

cmaas opened this issue Sep 27, 2019 · 19 comments
Labels

Comments

@cmaas
Copy link

cmaas commented Sep 27, 2019

Stencil version:

@stencil/core@1.5.2
@ionic/core@4.9.1

I'm submitting a:
[X] bug report
[ ] feature request
[ ] support request

Current behavior:
Stencil used to work in Safari 10.1+, but doesn't in the current version, because of a JS error. Older versions (Stencil 1.3.3 for example) still work.

Expected behavior:
Make it work again in iOS 10.

Steps to reproduce:
I created a new project with ionic-pwa, bumped the dependencies to the current version and uploaded the project here: https://stencil-ios01.netlify.com/
I installed a bunch of iOS Simulators to test it (iOS 9, 10.0, 10.1, 10.2, 10.3.1). Unfortunately, there are no simulators for the recently released iOS 10.3.4. If anyone has an older device (iPhone 5?) I'd appreciate a test on a device running iOS 10.3.4.

Results:
The "new" error is the first one (TypeError: invalid scheme). The other error (Cannot declare a let variable twice is a bug in Safari 10.3.1, but I'm not sure if it was fixed in 10.3.4: babel/minify#567

iOS 10.3.1 – JS errors:
10 3 1-error

Line of code referenced of first error:
10 3 1-code

iOS 10.0-10.2 (same first error as with 10.3.1):
10 2-error

iOS 9 – won't show because of CSS errors with variables.

Edit: I updated this issue a lot, after I tested with an older Stencil version, where everything works more or less as expected.

@ionitron-bot ionitron-bot bot added the triage label Sep 27, 2019
@cmaas
Copy link
Author

cmaas commented Sep 27, 2019

I installed an older version of Stencil (1.3.3). With this, it works at least somewhat on iOS 10.0: https://stencil-ios02.netlify.com/
So the bug must've been introduced in a more recent version of Stencil. Unfortunately, Xcode 11.0 doesn't let you download iOS 10.2 or 10.1 anymore.

@manucorporat
Copy link
Contributor

can you give 1.5.3 a try?

@cmaas
Copy link
Author

cmaas commented Sep 30, 2019

@manucorporat Uploaded here: https://stencil-ios02.netlify.com
Now silently fails to load on iOS 10.0 and iOS 10.3.1 without any JS errors, but shows a blank page only.

Couldn't get to try it in iOS 10.1 and 10.2 so far, sorry.

@cmaas
Copy link
Author

cmaas commented Sep 30, 2019

Fails silently on iOS 10.1 as well

@cmaas
Copy link
Author

cmaas commented Oct 2, 2019

1.5.4 is still broken on iOS 10.1 – I updated the page here: https://stencil-ios02.netlify.com/

Edit: I'll just try iOS 10.1 now, because this is the specified min version.

@arielsalminen
Copy link
Contributor

Latest versions fails silently on 10.3.3 as well.

@cmaas
Copy link
Author

cmaas commented Oct 2, 2019

@viljamis Oh great, someone with an actual 10.3.3 device. Glad you're here and can test 😄

@arielsalminen
Copy link
Contributor

arielsalminen commented Oct 2, 2019

@cmaas haha, yes, I have a pretty large device test lab I can use with mostly older devices. Just tested on a device running 10.3.4 as well. Fails there too.

@cmaas
Copy link
Author

cmaas commented Oct 11, 2019

1.7.0 still fails silently on iOS 10.1

@tricki
Copy link
Contributor

tricki commented Oct 18, 2019

Same for iOS 10.0.1, see #1963

@arielsalminen
Copy link
Contributor

arielsalminen commented Oct 25, 2019

Ran out of time yesterday while debugging this. But the issue is basically that Safari 10.x doesn’t support Stencil’s ESM build and just silently fails when trying to execute that. There seems to be multiple compatibility issues/features used that Safari 10.x does not support. Further, the “nomodule” build of Stencil has an IF statement in the beginning of it that prevents Safari 10.x from executing it.

The non-ESM build works in Safari 10.x though (seems to work perfectly even in Safari 9.x?!) and if using script tags on a basic webpage there is a way around this issue. This is a bit hacky though but I tested it to be working on older Edge, IE11, Safari 9-13, Chrome, Firefox and Opera:

<!DOCTYPE html>
<meta charset="UTF-8" />
<head>
  <script>
    /**
     * Safari 10.xx supports <script type="module">, but since the module build just silently
     * fails, this code makes sure that we load the nomodule version in older Safari instead.
     *
     * The below if-statement detects other browsers, except Safari 10.x and under:
     *
     * - History.scrollRestoration was only introduced in Safari 11.0.
     * - "onbeforeload" is a feature only found from Safari.
     */
    if (history && history.scrollRestoration || !("onbeforeload" in document.createElement("script"))) {
      // Builds regular module and nomodule script tags for most browsers
      var m = document.createElement("script")
      m.src = "/build/duet.esm.js"
      m.type = "module"
      document.head.appendChild(m)
      var n = document.createElement("script")
      n.src = "/build/duet.js"
      n.setAttribute("nomodule", true)
      document.head.appendChild(n)
    } else {
      // For Safari 10.x build a basic script tag that loads the polyfilled version
      var s = document.createElement("script")
      s.src = "/build/duet.js"
      document.head.appendChild(s)
    }
  </script>
</head>
<body>
  <duet-button>Stencil.js component that now works in Safari 10.x</duet-button>
</body>

Wondering now though if @manu or someone else in the Stencil team has ideas on how we could make Safari 10.x load the non-ESM build instead in Stencil itself. The IF statement I have in the above example should work well enough for this use case as history.scrollRestoration was only introduced in Safari 11.

@bbellmyers
Copy link
Contributor

This is a major blocker for us upgrading from 1.1.1 to the latest Stencil version. This is happening on IE11 Storybook/React as well. https://stencil-worldwide.slack.com/archives/C79EANFL7/p1570827052090600

Stencil-1 7 4-versus-IE11-Storybook

@CSchulz
Copy link
Contributor

CSchulz commented Nov 15, 2019

I am wondering why the entry.js file contains already the condition shown by @viljamis but doesn't seems to work or is this just an extra condition to prevent duplicate execution?

Stencil 1.7.2

'use strict';
(function() {
    var doc = document;
    var currentScript = doc.currentScript;

    // Safari 10 support type="module" but still download and executes the nomodule script
    if (!currentScript || !currentScript.hasAttribute('nomodule') || !('onbeforeload' in currentScript)) {

@danjohnson95
Copy link

Similar to @viljamis, we're currently working around this issue by only inserting the non-ESM build for Safari 10.x

var isSafari10 = window.navigator.userAgent.indexOf('Safari') > 0 && window.navigator.userAgent.indexOf('Version/10') > 0;
var esmBuild = document.createElement('script');
var nonEsmBuild = document.createElement('script');

esmBuild.setAttribute('src', '/build/components.esm.js');
nonEsmBuild.setAttribute('src', '/build/components.js');

if (isSafari10) {
    document.head.appendChild(nonEsmBuild);
} else {
    esmBuild.setAttribute('type', 'module');
    nonEsmBuild.setAttribute('nomodule', true);

    document.head.appendChild(esmBuild);
    document.head.appendChild(nonEsmBuild);
}

@dutscher
Copy link
Contributor

@CSchulz the problem is that is loaded but not executed due the "nomodule" attribute.

@dutscher
Copy link
Contributor

dutscher commented Nov 15, 2019

How to implement the modules right isnt well documented from ionic.
See here: https://stenciljs.com/docs/javascript
And here: https://github.com/ionic-team/stencil#hosting-the-app
But here we can find the none working implementation: https://stenciljs.com/docs/output-targets#differential-bundling

I would expect this in the README.md, or i expect too much?

And how they tested their Safari 10 bugfix? https://github.com/ionic-team/stencil/blob/master/CHANGELOG.md#-153-2019-09-27

cheers

@dutscher
Copy link
Contributor

dutscher commented Dec 17, 2019

btw safari 10.0 on ios has a old webkit.performance api https://developer.mozilla.org/de/docs/Web/Web_Components

and breaks silently at performance.mark(), performance.measure & performance.getEntriesByName

to get rid of use stencil build --no-profile
thats the solution for old safari, tested on core 1.7.4

cheers

@adamdbradley
Copy link
Contributor

Thanks everyone for helping to debug this! @viljamis awesome job tracking down how to test for safari 10. The fix deals with:

  1. Safari 10 supports ES modules
  2. Safari 10 does not prevent downloading nomodule scripts (it'll request both esm and systemjs)
  3. Safari 10 does not support async/await

So all that combined, it's best to always have Safari 10 use the es5/system build. The problem is that it'll always request both the esm and systemjs builds, so in this special case, we want the esm build to not continue to execute, while the systemjs should. Luckily this didn't add too much code, and when the day comes we do not have to worry about supporting Safari 10, these if statements can someday be removed.

We'll be able to get this shipped in both the next 1.8.x release and 1.9.x prereleases.

Thanks everyone!

@cmaas
Copy link
Author

cmaas commented Jan 13, 2020

Perfect, I can confirm that Stencil 1.8.5 works in iOS 10.3.1. Thanks for the work!

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

No branches or pull requests

9 participants