ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.56k stars 784 forks source link

[Old Firefox] Syntax error in strict mode #1712

Closed fabiolibre closed 5 years ago

fabiolibre commented 5 years ago

Stencil version:

 @stencil/core@1.1.3

I'm submitting a: [ x] bug report [ ] feature request [ ] support request => Please do not submit support requests here, use one of these channels: https://stencil-worldwide.herokuapp.com/ or https://forum.ionicframework.com/

Current behavior: Trying to load the nomodule file on an old browser will throw a warning in the console that prevents the entire file from being executed:

SyntaxError: in strict mode code, functions may be declared only at top level or immediately within another function

This is because the CustomEvent polyfill defines a function inside a conditional block, which is not suppose to happen in strict mode.

Removing 'use strict;' from the beginning of the file fixes the issue.

Expected behavior: Old browsers should be able to load the polyfills.

Steps to reproduce: Open a simple page using on Firefox 33. The stenciljs generated file won't be loaded and no custom element is defined in the page.

Related code: This snippet is taken from the dom.js file and is the part FF complains about.

// Polyfill CustomEvent
if (typeof window.CustomEvent !== 'function') {
  function CustomEvent(event, params) {
    params = params || { bubbles: false, cancelable: false, detail: undefined };
    var evt = document.createEvent( 'CustomEvent' );
    evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
    return evt;
  }

  CustomEvent.prototype = window.Event.prototype;

  window.CustomEvent = CustomEvent;
}

To solve the issue, just defining CustomEvent diffently, like:

// Polyfill CustomEvent
if (typeof window.CustomEvent !== 'function') {
  CustomEvent = function(event, params) { .. }
  .
  .
  .
}

This commit added 'use strict'; inside getSystemLoader(). which caused the problem.

async function getSystemLoader(config: d.Config, corePath: string, includePolyfills: boolean) {
  const polyfills = includePolyfills ? await getAppBrowserCorePolyfills(config) : '';
  return `
'use strict';
${polyfills}

Other information: Since the focus is to support newer browsers, a quick fix might be to remove 'use strict;' from getSystemLoader(). Alternative is to follow the use strict and modify dom.js like explained in the Related code: section.

fabiolibre commented 5 years ago

I'am creating a PR for this issue. https://github.com/ionic-team/stencil/pull/1713

CSchulz commented 5 years ago

Also an issue with old safari versions and maybe chrome both on iOS.

chenyulun commented 3 years ago

"Mozilla/5.0 (Linux; Android 5.1.1; vivo X7 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 MyAppHybrid/3.4.0 (MYAPPNAME 4.39.0) UnionPay/1.0 MYAPPNAME deviceId/AUUID_d0d6a8dc52d4247cc815328f5d72cca9b7abb81e deviceType/1 device-dpr/3.0 device-dr/640.0*360.0 networkState/WIFI"

Uncaught SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.
chenyulun commented 3 years ago

If Safari 10 checks exist, do 'use strict; ' 'in a conditional statement

// 'use strict'; // Comment out this line
(function () {
  var currentScript = document.currentScript;

  // Safari 10 support type="module" but still download and executes the nomodule script
  if (!currentScript || !currentScript.hasAttribute('nomodule') || !('onbeforeload' in currentScript)) {
     'use strict'; // Add this line
     // ... other ployfills code
  }