atomicojs / atomico

Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.
https://atomicojs.dev
MIT License
1.15k stars 43 forks source link

How to test for browser compatibility? #69

Closed shah closed 2 years ago

shah commented 2 years ago

Is there a simple function I can use like isBrowserAtomicoCompatible that I can call on any page to warn the user that my site/page may not work in case their browser is too old to support Atomico?

UpperCod commented 2 years ago

Hi, I just added the atomico@1.35.0/utils module, with which you can check the incompatibility of Atomic with the current browser:

import { checkIncompatibility } from "atomico/utils";

const check = checkIncompatibility();

check.length && alert("Please add the following polyfill "+ check);

The return is an array with what is missing for atomic to work, the idea of this is to have a list to import the polyfills easily, example:

<script type="module">
import { checkIncompatibility } from "https://unpkg.com/atomico@1.35.0/utils.js";

checkIncompatibility().forEach(key=>{
    switch(key){
        case "customElements":
            polyfillCustomElements();
        break;
    }
})
</script>

Remember Atomico minimally requires esm modules to work, since Atomico is a library that is distributed without the need for compilation.

shah commented 2 years ago

This is great, thanks for putting it together @UpperCod - out of curiosity, should the check be done with just <script> tag without ESM to be able to trap incompatibility? Meaning. if import { checkIncompatibility } from "atomico/utils" fails, how would one catch that earlier?

UpperCod commented 2 years ago

Atomico is totally dependent on ESM when used without packaging tool, the other strategies I can think of are:

  1. Dynamic import
import("https://github.com/atomicojs/atomico/blob/master/utils.js")
  .then(({ checkIncompatibility }) => checkIncompatibility().map(myPolyFill))
  .then(() => import("./my-webcomponent-with-atomico.js"));
  1. Bundle tool, distributing the components both in module and non-module format, in this case checkcompatibility can help to build a conditional polyfill to the browser

Now about the leveraged compatibility of Atomico, for now I have detected these:

  1. Esm
  2. Arrow functions
  3. Template string
  4. Spread operator
  5. CustomElements and shadowRoot (checkCompatibility)
  6. Map (checkCompatibility)
  7. Symbol and Symbol.from (checkCompatibility)
  8. Append and prepend (checkCompatibility)

For which browser version are you looking to extend Atomico compatibility?

shah commented 2 years ago

Yes, the dynamic import should work for me @UpperCod - basically, I would like to suggest users use a "modern" browser (and we can give them any recommendations) as long as we catch their incompatible browser without crashing. We don't need to worry about working on older browsers or with polyfills, just catching older browsers and giving users a suggestion based on their OS.

UpperCod commented 2 years ago

I understand, this script could be useful to you:

<script>
  try {
     Function(
      [
        'import("data:text/javascript,export default 10");',
        "class A extends HTMLElement {}",
        "customElements.define;",
        "new Map();",
        "Symbol();",
        "Symbol.for('a');",
        'if (!("prepend" in Element.prototype) || !("append" in Element.prototype)) {throw "";}',
        "`${1}`;",
        "return true;",
      ].join("")
    )();
  } catch (e) {
    var node = document.querySelector("#obsolescence-message");
    if (node) node.style.display = "block";
  }
</script>

In summary, it is a function that defines necessary characteristics for webcomponents and Atomico, this function will fail if one of the characteristics does not exist or if the syntax is not supported, when it fails it can show a predesigned message for the browser.

Is it useful to you?, I wait for your feed to create a standard solution to distribute by Atomico

shah commented 2 years ago

Yes, that's very helpful -- thanks! I would want to include the standard solution in each of my pages and, in case Atomico is not supported due to lack of capabilities I could redirect to a page suggesting that they download an upgraded browser. On that page we would try to see which platform (Win/Linux/MacOS) and make appropriate browser and version suggestion.