What is the significance of browserslist in package.json created by create-react-app - create-react-app

I was asked this in an interview. I could not answer.
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
I can see that Its an array.
"not ie <=11" means will not run on lower than Internet Explorer v11
"op_mini" must be related to Opera mini.
But I want to know why it is required.

What is Browserslist?
Browserslist is a tool that allows specifying which browsers should be supported in your frontend app by specifying "queries" in a config file. It's used by frameworks/libraries such as React, Angular and Vue, but it's not limited to them.
Why would we want it?
During development we want to use the latest javascript features (e.g ES6) as it makes our jobs easier, leads to cleaner code, possibly better performance.
As javascript evolves, browsers won't support new features at the same pace, for instance not all browsers have built-in support for ES6 (aka ES2015). By using browserslist, transpilers/bundlers know what browsers you want to support, so they can "group" browsers in different categories and generate separate bundles, for example:
Legacy Bundle: Contains polyfills, larger bundle size, compatible with old browsers without ES6 support.
Modern Bundle: Smaller bundle size, optimized for modern browsers.
So our entrypoint (e.g index.html) is generated in a way that it'll load the required bundles according to current browser being used by a user.
This process is done by Angular, Vue and React. In the future, bundler tools may generate even more bundles depending on how different browsers are, one bundle per group of browsers. Generating more bundles optimizes your app even more, at the price of making the build slower (and more complex), it's a tradeoff.
Let's see each individual query in your example:
0.2%: All browsers that have at least 0,2% of global market share
not dead: Exclude browsers without official support in the last 24 months
not ie <= 11: Exclude IE 11 and older versions
not op_mini all: Exclude Opera Mini
You can find more about it (including further query options) in Browserslist's GitHub repository.

That's a React configuration option to know which browsers the build process should target to.
As the documentation says:
The browserslist configuration controls the outputted JavaScript so that the emitted code will be compatible with the browsers specified.
If you are intend to use a ES feature make sure all browsers specified supports it, otherwise you have to include polyfills manually. React will not do it for you automatically.
See more in: https://facebook.github.io/create-react-app/docs/supported-browsers-features and https://create-react-app.dev/docs/supported-browsers-features/

Related

Vue project with or without Babel?

I am using Vue CLI to create a Vue 2.0 project and one of the options is using Babel. I understand Babel is a transpiler but what exactly does it do? I created a project with it and another without it and I don't see the difference so what exactly is the pro/con of it ? I can't see offhand what it is doing.
You are correct. Babel is a transpiler. It transpiles your JavaScript code to one or more taget browsers, that does not support the lastest fetures. You will not see any difference, if using a newer browser.
Babal usually only makes sense if you need to support older browsers, like IE 11 or browsers from before 2017.

How to detect features and lazy-load only the needed polyfills with babel / core-js?

Polyfill services like polyfill.io seem to be delivering only small feature detects to the browser and then lazy-load only the polyfills that are actually needed.
As I understand the babel documentation on polyfilling, babel always include the full set of potentially needed polyfills: it will process a browserslist and then include those polyfills from core-js that the weakest browsers need. A bundler like webpack would then probably merge all these polyfills into the application, but without runtime feature detects.
My application uses modern ES language features but also targets a wide range of browsers, including IE10 and IE11. That requires a lot of polyfills and will probably bloat the bundle, especially for modern browsers that may not need the most of the polyfills.
So I was wondering: can I tell either babel and/or webpack to only include feature detects, split the polyfills off into separate chunks (individually or into small bundles), and then, at runtime, only "lazy"-load what is actually needed?
Services like polyfill.io investigate your User Agent against a predefined set and based on that provide you with different bundle of polyfills. What you're trying to do is actually way different.
One solution I could thing of is to introduce code splitting into your build (it is on by default in Webpack 4 production build) and create several files in your project, where each would import a different set of polyfills. This will require you to import polyfills manually, but will allow you to have several polyfill chunks, each with a different subset of missing features. After you will have those chunks, you could use some feature detection (probably Modernizr) on the startup of your application and dynamically load only those chunks which are needed by the browser. Keep in mind that this process is rather cumbersome - you will need to take care of including each polyfill manually. Also another disadvantage of it, it will need to make several requests to the server, which will additionally slow down your app start time.
As to other part of your question - webpack/babel will not do the automatic polyfill chunks splitting and runtime feature checking for you, those will need to be handled manually.

'Gatsby develop' support for IE11

Say I wanted to support IE11 (and sadly, I do), how would I go about making gatsby develop work on that poor old browser?
Right now, I get this message:
webpack-hot-middleware's client requires EventSource to work.
This polyfill looks promising, but that's as far as I've made it.
Any help?
P.S. Probably worth mentioning that I'm using Gatsby v 2.4.7
Looks like Gatsby doesn't support IE in development, only in production, so no polyfills will be added and IE will error when using gatsby develop.
https://www.gatsbyjs.org/packages/babel-preset-gatsby/
Can confirm on my project that running gatsby develop doesn't make it work for IE11, but using gatsby build does. When running gatsby develop, all I could see on IE11 is a blank page.
As per the documentation of Gatsby, You need to use babel 7.
Babel helps ensure the JavaScript you write works across different browsers (including older versions of Internet Explorer).
Reference:
Babel 7 (Gatsby)
Gatsby leverages Babel 7’s ability to automatically add polyfills for your target browsers.
Newer browsers support more JavaScript APIs than older browsers. For older versions, Gatsby (via Babel) automatically adds the minimum “polyfills” necessary for your code to work in those browsers.
If you start using a newer JavaScript API like [].includes that isn’t supported by some of your targeted browsers, you won’t have to worry about it breaking the older browsers as Babel will automatically add the needed polyfill core-js/modules/es7.array.includes.
Reference:
Browser Support

Why does Aurelia install so many dependencies?

I am curious to know why when I create a new Aurelia project, each project installs +600 node_modules. Understandably, the modules collectively don't take up a lot of space, but are all of these modules necessary? I was under the impression that Aurelia's aim was to help developers move away from depending on 3rd party libraries so it seems odd that each project comes with a massive dump of 3rd party libraries.
My guess is that you are starting your project from CLI - which comes preset with HTTP server, ES6/2015, SASS, live-reloading and more.
I created clean Aurelia project and looked at the package.json - there were 5 dependencies and 34 dev dependencies. Using all of above mentioned tools is somewhat standard in today's JS web development, and generating project from CLI reduces time needed for upfront setup. All of these features come with their own dependencies, and that's why node_modules/ folder grows rapidly.
The bottom line is - you could start new Aureila project with much fewer dependencies. On their home page you can find starter project with just three. But that also means that you won't have access to most of the tools used today.
Also, and correct me if I'm wrong, I haven't got the impression Aurelia ever aimed to move devs from third party libs and modules, just to be modern, fast, and unobtrusive.
All modern web frameworks have a host of tooling. The reasons in no particular order -
1. Transpiling ESNext or TypeScript - if you want to write in Future JavaScript but have it work in all browsers, you need this step. Both Babel and TypeScript tooling comes with extra stuff too. If you want to see coverage (everyone does) there's another tool.
2. Testing - Unit test and End to End testing require testing frameworks, test runners, and if you want to write like above (esnext or TypeScript) you also need transpiling.
3. Module Loading / Bundling - Require.js, JSPM/System.js, WebPack, etc... are used to allow your code to actually run in the browser. Without a module loader you could not break your code out in to separate files. Without a bundler you would be loading a lot of extra files in production.
4. Serving your application - If you want to run your app locally you need a way to serve it up and watch for changes.
5. Debugging - You want to debug? Now you need a way to debug the file that gets served to the browser back to the original source.
6. Linting - Lint your code base for style consistencies.
Each of these packages usually have their own dependencies, and they get pulled down as well.
This convention of small packages that have a single focus is arguably better than massive packages that do everything for you. This allows you to remove a package and replace it with the one that does the same thing but in a way you want it.

TypeMismatchError on post

I'm writing an aurelia application with aurelia-fetch-client library.
When I try to post an object to my api service I get the error:
TypeMismatchError
In console only from Edge. Other browsers (Chrome, Firefox and IE11) have no problems. There are no description or any other details about it.
In all but the newest versions of Edge you need to include the fetch polyfill in order for aurelia-fetch-client to work. I think it's supported since version 14 but I wouldn't necessarily rely on it. Edge is known to be quirky with some of these things (the Promise implementation is also horribly slow, which is why I personally always use bluebird)
You can install it with npm i whatwg-fetch --save and make sure to import it + include it in your bundle config (the instructions for this depend on which build system you're using)