Steven Kleiman - 2022-07-05

I have a policy of not using new language or browser features until they’ve been in the field for 5 years. Now that ES6 (ES2015) has past that point I’m working on upgrading the infrastructure to make use of it.

I’m very happy with the state variable approach from the current framework and intend to reuse the approach while cleaning up the spaghetti code for input and output. I’m also happy with the MVC-style model and page interface.

In the last rewrite I tried to take a Web Components style view and built a framework based on JSON templates due to the limitations of ES5 and borrowing some ideas from Angular. This time the obvious framework to consider is React and I’ve been experimenting with it extensively. One negative is that much of the React community relies on the Babel, JSX, and Webpack workflow. I’ve rejected this workflow for several reasons:

  • The Webpack syntax is non-standard (e.g. import ‘xxx.css’) and incompatible with ES6 modules. I often find that these non-standard facilities are invented due to limitations in the JavaScript and DOM that are eventually cured by the standard. That’s one reason the app use JQuery very lightly.
  • Similary, Babel made ES6 avilable to browsers that didn't support it. That's not a big issue today, so why transpile?
  • The Babel, JSX, and Webpack workflow requires source maps. So far my experience is that source maps work 90% of the time and when they don’t you’re left debugging with console.log. It reminded me of bringing up hardware with glass TTYs in the 80’s (shiver).
  • I’m not sure that bundling is required for this app. The mobile devices that may have restricted bandwidth use Cordova which means all the files are local. Computers with browsers usually have high speed connectivity. I’ve not noticed much difference between the Cordova version startup time as compared to the Web version even with an empty cache. Besides which the airport DB often takes up a significant percentage of the app size (30% to 50%) and bundling and tree shaking won’t help that.

The real downside to this decision is that I won’t be able to directly import third-party React components. However, the components I’ve looked at often drag in other components and libraries which can lead to uncontrollable bloat. Maybe someday React will have the ability to export ES6 Modules.

React is still usable without JSX (or Babel and Webpack) as a library. Instead of JSX I’m exploring an ES6 template-string approach based on htm (https://github.com/developit/htm). This allows me to incorporate the Moustache-like state variable reference syntax from the current framework. It also allows me to extend the HTML-like syntax in other ways, such as adding extensible character entities that can even support custom SVG symbols. Very cool. Instead of Webpack I’m using standard ES6 Modules.

The alternative to React is modernizing the current framework technology that has served the app so well up to now. I’m actually doing a test implementation of both. It was difficult to hook up React components to external State Variables, but it’s done. I haven’t chosen a winner yet but I’m leaning against React, because:

  • Component children in React are supposed to be opaque. This is a problem when the semantics of the parent depends on the children. For example. The particular case I’m thinking of is checklist procedures in XML where each step components to extract the item and action from its children.
  • Implementing easy components in React is easy, but implementing more difficult components in React is more difficult because you have to manipulate both the DOM (e.g. in the pointer event handler) and React’s pseudo DOM (setState, useEffect etc). It’s not clear how much you can manipulate the DOM directly before you break React.
  • React’s DOM diffing means that “key” properties are required. This actually imposes a significant burden on the Component user.
  • The modernized version of the current framework is structured a but like React, but the component has full control of the DOM. It can operated at the component level, the template level or the DOM node level. Unlike React, change only happens during the sync phase and the component can simply update values instead of re-rendering.

What I’ve discovered so far, is that from the point of view of a page coder (as opposed to a Component coder), there is little difference between the two approaches.

If you have some experience as a React developer please let me know. I’d really like some help finalizing the decision.

Steve

 

Last edit: Steven Kleiman 2022-07-07