Just yesterday gave a quick training session on Async functions and Promises... One of the few times I've used typescript, only to reinforce that Async functions return a promise, and can await on promises, to show a function returning a promise is effectively the same. As well as Promise.resolve and Promise.reject for use in mocking for tests.
For pretty much everything I'm working on now, I cut off with fetch and async function support (around April 2017 and newer browsers). In node, I use node-fetch or setup a global if I'm sharing code libraries.
While fetch isn't perfect, usually create an api wrapper around it. It's standard, cleaner than alternatives and built into the browsers (smaller bundles).
Yeah... the preflight check should be a must... same for a <noscript> at load, which I don't do. Anyone that has scripting disabled is likely to know what they're getting and why. IIRC, iOS 11 (april/may 2017) is the break point for async and supports iPhone 6 and 5S I think.
Most of my work is internalized apps, but at this point even public facing it's probably a fair cutoff. Killing the async/generator transforms is a pretty big improvement... I'd love to see a modern server that detects behaviors and pushes the mjs most likely to be requested from an initial starting point.
These days charting libraries are about the only thing too big imho that should be lazy loaded when needed. I try to keep my app bundles under 500k, which includes styling and a layout images. Larger than I'd like, but given the landscape reasonable for the effort.
Very cool... My hope is that eventually the browser's JS engine will add a jsx pragma directive that will allow you to specify your jsx translation in the browser + js.
That said, I've all but dropped legacy (IE11) support and break at anything that doesn't support async functions .
// index.precheck.js
try {
eval('(function() { async _ => _; })();');
} catch (e) {
window.location.replace('/legacy.html');
}
With the above precheck in place, I have my main index.js generated via the following babel configuration... It specifically excludes the async/generator transforms which are freaky huge... without them, my bundles are a decent size.
// .babelrc
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"useBuiltIns": "usage",
"targets": {
"browsers": "> 5%"
},
"exclude": [
"transform-async-to-generator",
"transform-regenerator"
]
}
],
"@babel/preset-react"
],
"env": {
"test": {
"plugins": [
[
"@babel/plugin-transform-modules-commonjs",
{
"allowTopLevelThis": true
}
],
[
"babel-plugin-dynamic-import-node",
{
"noInterop": true
}
]
]
}
}
}
Vue + Google Tag Manager === holding old DOM nodes in memory
The fix itself is somewhat sloppy. That said, it's worth understanding. Not sure if GTM would do similar with refs if you're using React and tbh, not sure how much value GTM actually adds in practice. It may really only apply to Vue and GTM combined.
Used to see this type of problem a *LOT* with SPAs in IE prior to version 8, as JS and the HTML renderer were in different memory spaces, so either side holding a handle wouldn't know about the other releasing the reference. One thing very cool if you used jQuery once it came out, as it would release both sides if you used jQuery for your event binding and DOM manipulation. This is less of an issue in modern browsers.
In this case, you have two sets of code holding references to DOM nodes, the UI itself and GTM. I'm unsure if their fix actually breaks GTM and it seems it probably does. So even then, not sure wth the point is.
If you're wrapping the response from fetch for an error, I would suggest using
throw Object.assign(new Error("Fetch Error"), { response });
This gives you the full context instead of response.toString() as the error message.
Something I do in practice for my API endpoints is always return {result} or {error} from my API. An object where a root error can be checked against, or the result... This way I can have a very consistent handler, which is usually a wrapper around fetch as I'm not currently supporting any non-green browsers and fetch has been around for long enough now.
Very cool... would love to see a style method that works with material-ui and JSS... would just need a function that accepts a theme, and then use that theme combined with positional definitions `"& .subclass"` to target children... this way the styling can match material-ui while still keeping its' component structure... I haven't looked at the CSS or rendered markup to determine any of this, only know that it's possible.
edit: created feature request.
https://github.com/Adphorus/react-date-range/issues/347
One thing to note, is that with HTTP2+ if you can push many of the required baseline .mjs files to your client, or setup an appropriate manifest for offline caching it will dramatically improve performance. Having a request based model will mean much lower load times over slower/intermittent networks (phone/wireless).
I really do think that this approach is the future, even if I'm not sure how well this will integrate with the broader JS community in the near term. I also think there's maybe another year or two to flush out some adjacent utilities to help with initial load of projects like this into a browser. I hope that a packaging system (deliver zip or tarball to browser) gets traction and takes hold.
Something to note: Other than local/development, and even for testing, don't put your production configuration into .env files... either generate it from a template in your ci/cd pipeline, manually generate it and/or use the actual environment to specify said settings.
Another aside, I really tend to prefer the URI syntax for connection strings, this allows for a single setting to contain protocol, user, password, host, port, database and additional options. While it's a more complex string, it's fewer things that need to be set in terms of environment variables and secrets and the more applications/services you are setting up the more you will appreciate the convention.