wearereasonablepeople / warped-components

:cyclone: An opinionated way to build frontend applications
MIT License
18 stars 0 forks source link

Ensure code is ready for browsers #9

Closed Amri91 closed 6 years ago

Amri91 commented 6 years ago

We have Object.entries, Set, Map, and many many more :open_hands: :person_with_blond_hair:. I think it is easiest to just transpile the code. I will create a PR soon.

Avaq commented 6 years ago

Each of those features are supported in all major browsers. People targeting unsupported or old browsers can bring in their own polyfills. I'm not sure whether the benefit of supporting non-standard environments out of the box outweighs the added complexity of code transpilation.

Avaq commented 6 years ago

Is there any feature in particular you feel does not have a widely enough spread adoption to safely use?

Amri91 commented 6 years ago

I am referring to the libraries warped-components, react-collect, and warped-reducers.

We were trying to write ES3 (or ES5?) code to avoid the compatibility issues, however, we ended up with ES 2017 features such as Object.entries and Array.from. Assuming we still want to support es5, these new features needs to be included somehow or we need find an alternative for it. Otherwise, we might need to provide a compatibility table.

I think it is OK to keep using the new ES features, it also has the extra benefit of making implementation easier and that brings other benefits as well.

Old projects will just have to use .js and lose some tree-shaking the benefit of which is limited due to the size of the libraries. Newer projects will be able to use the .mjs files.

Do you prefer to support ES5 as opposed to ES6+? There are multiple ways to do this, do you prefer a specific way?

dicearr commented 6 years ago

In order to keep both compatibility and tree shaking, we could create 2 transpiled versions. It would be an original index.mjs file compliant with es6, a fully transpiled version index.js file compliant with es3 and for those that may want to use es3 but having tree shaking we can generate an intermediate file es3-modules.mjs.

So index.mjs can be transpiled with babel setting modules: false. This will generate es3-modules.mjs. Then es3-modules.mjs can be sent to rollup in order to generate index.js.

With this approach we cover the whole spectrum, giving to everyone the possibility of using tree shaking. The drawbacks are: it adds complexity to the project and in case you want to use es3 and tree shaking you need to point directly to warped-components/es3-modules.mjs.

Avaq commented 6 years ago

There there three distinct compatibility concerns:

  1. The module system: Node 10 and up, moderns browsers, and build tools such as Webpack can utilise the new modular JavaScript features that have been specified in the later EcmaScript specs. This is all about how the code is loaded and has little to do with the other two concerns.
  2. Syntax: As JavaScript evolves, new syntax is added to the language. When new syntax is used, you can be sure that older versions of JavaScript will not be able to run your code. It is therefore a good practice as a library author not to rely on recent syntactic additions to the language, as they make your library incompatible with older environments.
  3. APIs: As JavaScript evolves, new global APIs are added to the language. Think of Array.prototype.forEach, Promise, Map, Set, Proxy, etc. These APIs are available by default on newer environments, but can be polyfilled on older environments.

What we're trying to achieve as a library author, is to cater to as many environments as possible, with the least possible technical overhead and cost to maintainability.

My approach to each of the concerns is as follows:

  1. The module system: We provide the source code using the new, static, module system. This means build tools can benefit from the static guarantees, allowing them to create smaller bundles, and it's the way forward with regards to browsers and Node. Sadly, some tooling has been left behind, and uses hard-coded loaders to analyse the code. This is why we provide an alternative index.js file.
  2. Syntax: We simply don't use new syntax features. The language is just as complete without them, and it makes the code directly compatible with all environments.
  3. APIs: We can use modern APIs, and users bundling our code for older environments can use es-shim or a similar compatibility package to polyfill these APIs.

I don't feel that adding polyfills to our code is our responsibility, nor does it provide any benefit to our users, who likely already use their own polyfills in case they target older environments. The drawbacks of providing our own polyfills (through babel, as suggested) are:


My vision for this project, as well as all other open source projects I maintain, is that I will soon be able to remove the compatibility fallback (index.js) and publish only index.mjs. Build and test tools will catch up, and will be able to load this format without any problems. Browser can load this format directly. Node can load this format directly. For older version of Node there is esm and for older versions of browsers there are build tools.

Amri91 commented 6 years ago

fair enough, I will close the relevant PRs then