Whats the difference between babel-preset-es2015 and babel-preset-env? - javascript

I'm currently trying to understand about babel configuration, but got confused by babel-preset-**, there are many preset in babel, like env, es2015, react and others, I do understand that babel-preset-es2015 is needed to transpile es2015 code to previous js code so it can be understood by most/older browser, what about babel-preset-env?
What are the differences between those presets? Can one use env without using es2015 or vice versa? and what are the cases when we need those two presets to be present on our project build system?
Thank You.

The babel-preset-es20XX (15, 16, 17) presets include transforms needed to convert features added in that specific year to code that is compatible with the previous version.
babel-preset-env includes transforms for all features that have landed in the spec, but only enables the ones needed to make the features work based on the set of environments you've provided to it. If you pass no options to env it essentially works like es2015, es2016, es2017 all together.
babel-preset-react is the set of transformations needed to convert React/Facebook-related syntax extensions like Flowtype and React's JSX.

Related

What governs the ECMAScript version in a create-react-app?

I am currently running a create-react-app, using react v16.2. I would like to use Optional chaining from ECMAScript 2021 (ES12). What governs the ECMAScript version in my app?
For example, in a nodejs backend app I know I need to upgrade my version of node, but I'm unsure how this translates to React.
EDIT - I'm currently on v16.2 and when i try to use optional chaining, I get an error message asking me to use a babel polyfill.
React uses Babel to transpile and polyfill the code i.e. convert your ES2015+ code to ES5 syntax. create-react-app uses Webpack as the build tool and Babel as the transpiler so you should safely be able to use the optional chaining ? syntax and when you run / build your app, it will work as intended.
Babel is what decides this, it's a JS-to-JS transpiler. In create-react-app, you get whatever plugins and presets the maintainers decided on, unless/until you decide to eject so you can manage your own config. If you do decide to do that, you can start with the config they provide and then add new babel presets and plugins on top of that. As of a couple years ago, there's no good way to add to their config without ejecting. For your specific need, it looks like they include that plugin, so if your dependencies are up to date, you should be good to go.

Babel v7? Is it core-v7, cli-v7? or all packages are upgraded?

I understand Babel is a monorepo and contains a lot of packages like core, cli, plugins, presets etc.
When they say upgrade to Babel v7.x.x, what do they really mean. Does it mean, upgrade each of the packages in monorepo to v7.x.x?
If I upgrade my core package to babel-core-v7.x.x. Then does it mean if I still supply stage-x presets in .babelrc, core package won't understand it and hence won't transpile using the plugins in the preset.(Since stage-presets are deprecated in v7.x.x)
Babel Docs for Decorator plugin Here they say, In Babel 7, transform-decorators-legacy will be the default plugin in Stage-0. What do they mean here, if stage presets i.e. stage-x(0,1,2,3) are deprecated.
After playing around a bit, this is what I found.
Babel is a monorepo that has a lot of packages in it. The main babel package that takes the raw code and transpile to a new code is babel-core. By itself, it does not do anything, it simply returns the same code.
Babel-core or babel can accept config which could contain a lot of plugins, presets(bundled set of plugins). These plugins are responsible for transipiling code. For Eg. You may use an ES6 arrow function in your code. Then you may run babel with a plugin that transpiles arrow functions to get the resulting ES5 version of arrow function.
Now Babel v7.x.x is a major(as per semantic versioning) version change(from 6.x.x to 7.x.x), hence it is expected to have breaking changes. Hence if you just change the babel core version, the code is expected to break. Hence they supply a migration guide as well.
With version 7.x.x, the way Plugins/Presets are mandated to return a function against version 6.x.x where it could return an object or function. Hence if you try to use a v6 plugin, that return an object with v7 of babel core, it will fail. Also they have removed stage-x presets. Hence if you have those in your config, it will break as well. There are a lot of such changes. Please refer to migration guide.
To answer #3, I confirmed with the team there, and the docs are not updated yet.

How to publish React Component that is a class to NPM without having uglify.js issues?

I rewrote ES5 package to modern syntax to avoid deprecation warnings and published it to npm.
Most React projects, including ones based on next.js and create-react-app use uglify.js and they break at class keyword.
{ Error: commons.js from UglifyJs
Unexpected token: name
...
How do I properly write React component that uses class and works with uglify.js and npm?
React.createClass has been deprecated because it's going to be removed from the main react package in an upcoming version, but you can still use the now-separate create-react-class package instead if you still need/want to write components using it without getting deprecation warnings.
If you're using ES6 classes to write components which will be published to npm, you will need to add a transpile step so you're publishing ES5 code to npm for the forseeable future because - as you've seen - tools which don't support ES6 will break on them, and apps which use them will break in browsers which don't support ES6 classes natively (e.g. IE11).
If you already have Babel set up to transpile JSX, transpiling classes away before publishing isn't much extra work - install the babel-preset-es2015 preset and add it to your Babel config.
Even when we reach the point where ES6 support in tools and browsers is no longer an issue, standard ES6 classes aren't a very convenient way to write React components compared to createClass, as they introduce constructor boilerplate, need manual method binding and having to declare static properties such as propTypes separately.
It's common to use experimental implementations of proposed language features (babel-preset-stage-2 covers the most useful ones) for those convenience features to overcome this (even the documentation above about writing React components without ES6 has an example of this) and transpile them away with Babel plugins, so if you use these features you will have to keep transpiling your code anyway!

What is the difference between babel-plugin-* and babel-preset-*

I am using both plugin and preset and my current react app but technically I am not able to make someone understand what is difference between preset and plugins. For me both are the javascript file which used by babel loader to compile the code.
In short, a babel preset contains multiple babel plugins.
For example, if you only use arrow functions, you only need the transform-es2015-arrow-functions plugin. If you use a lot of ES2015 features, you better use babel-preset-es2015 which contains a lot of plugins including transform-es2015-arrow-functions.

VS Code - No ES6 Intellisense in TypeScript File

Can't quite figure out why I'm not getting intellisense for ES6 features in a TypeScript file.
I'm fairly certain it is related to the lib.d.ts file that is used in the typescript source files. For reference this is located in:
C:\Program Files (x86)\Microsoft VS Code\resources\app\extensions\typescript\server\typescript\lib
I noticed that the same folder contains lib.es6.d.ts. When going to definition on a method that is defined by the base interface definition files, it points you to lib.d.ts and not the es6 version. The es6 version has all of the interfaces that I need.
That said, even if I include some ES6 methods and force the task runner(which under the hood uses the typescript compiler installed), it doesn't transpile to ES5 like I expected it to.
Maybe my TypeScript compiler version is dated? Primarily I want these features:
Symbol
Array.prototype.includes
String.prototype.includes
I see these interfaces defined in the es6 typing definition file. Is there a way to get VSCode to recognize this? I'm thinking a hacky approach of just including that lib file in my project but I'm trying to avoid that and in the end it still doesn't solve my problem when I transpile to ES5 and get garbage.
Thanks and much love :)

Categories