ES6 module fails on Safari mobile (iOS14.6)

1.8k Views Asked by At

I'm experimenting with Javascript modules both via desktop (latest Chrome) and mobile (Safari with iOS 14.6) and my code works perfectly on the desktop (standard browser or mobile emulation mode) but fails on my iPhone. The imported JS code using <script type="module"> simply doesn't execute despite being supported since Safari iOS 11 onward according to https://caniuse.com/?search=modules

The test code below, adapted from How to serve ES6 modules on Safari? , is hosted on a webserver in my local network reachable by both the mobile & desktop clients. For mobile debugging I'm using a locally copied version of https://www.hnldesign.nl/work/code/mobileconsole-javascript-console-for-mobile-devices/ to render console.log commands on mobile.

test_ios.html

<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script>
      console.log("Start of test_ios.html...");
    </script>
    <title>TESTS IOS</title>
    <script src="/static/hnl.mobileConsole.1.3.js"></script>
    <script nomodule src="/static/fallback.js"></script>
    <script type="module">
        console.log("Starting the main script.");
      
        // The following line seems to cause an error in Safari only
        import { TestClass } from './static/test_module.js';
      
        // The rest is not executed due to the error
        let test_class = new TestClass;
        console.log("Done.");
    </script>
    <script>
        console.log("End of test_ios.html...");
    </script>
    <body>
    </body>
</html>

/static/test_module.js

export class TestClass {
    constructor() {
      console.log("Created a test class in test_module.js");
      document.body.append("test_module.js");
    }
  }

/static/fallback.js

console.log("Fallback.js");
document.body.append("Fallback");

Result on the desktop, as expected

Test string test_module.js gets written onto the web page & the following lines are in the console:

--==## Mobile Console v1.3.5 active ##==--
End of test_ios.html...
Starting the main script.
Created a test class in test_module.js
Done.

Result on iOS 14 - neither the module JS nor the fallback get executed

The page is blank (no document.body.append(...) was executed) & only the following lines are in the console:

--==## Mobile Console v1.3.5 active ##==--
End of test_ios.html...

Further checks already done:

  1. I sniffed the network and I see that /static/test_module.js is requested by the mobile device (no request for fallback.js).
  2. The content-type of /static/test_module.js returned by the webserver seems coherent (application/javascript; charset=utf-8).
  3. Renaming test_module.js to test_module.mjs doesn't help (same outcome as above)
1

There are 1 best solutions below

0
AlexN On

I found the issue: the following library broke the JS execution in Mobile Safari as soon as a call was done to console.log:

    <script src="/static/hnl.mobileConsole.1.3.js"></script>

Removing this library inclusion or/and replacing all calls to console.log by alert made the code above work as expected. The example code also feature minor errors (e.g. no </head> closing) but this wasn't the root issue.

I checked if jshint would have caught it in ES6 mode, unfortunately without success.

Takeaway for next time in case of issues with Mobile Safari: litter your JS code with alert boxes to see when / where it breaks :(