How do I get Babel 6 to compile to ES5 javascript?
Ecmascript 6BabeljsEcmascript 6 Problem Overview
I've installed the latest version of babel. Currently 6.4.0. I create a file called myclass.js that has the following code.
class MyClass {
constructor(name) {
console.log("I am a MyClass object .. ", name);
}
}
var myclass = new MyClass('1234');
after creating my class I do the following in the command line.
$> babel ./src/myclass.js --out-file ./out/app.js
I would expect my app.js file to have es5 compiled javascript but it has the same exact code in it that the myclass.js file has. What am I missing that may be causing this?
Ecmascript 6 Solutions
Solution 1 - Ecmascript 6
You don't tell Babel to target ES5, you choose the necessary presets/plugins that do that for you. For example, if you use the es2015
preset, this will compile ES6 code to ES5-compatible code. You don't specify a "target".
The guide below will take you through using Babel to transform ES6 code into code that can run in an environment that supports ES <= 5.
0. A note on API changes from Babel 5
In the documentation for Babel 6:
> The babel package is no more. Previously, it was the entire compiler and all the transforms plus a bunch of CLI tools, but this lead to unnecessarily large downloads and was a bit confusing. Now we’ve split it up into two separate packages: babel-cli and babel-core.
And:
> Babel 6 ships without any default transforms, so when you run Babel on a file it will just print it back out to you without changing anything.
______
babel-cli
1. Install First, as in the docs, you need to install babel-cli
:
$ npm install babel-cli
______
.babelrc
2. Define presets in Second, you need to use a .babelrc
(docs) local to your files and explicitly define the presets that you want Babel to use. For example, for ES6+ features use the env
preset.
> ...a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s).
Install it:
npm install @babel/preset-env
And then declare it in your .babelrc
:
{
"presets": ["@babel/preset-env"]
}
Note: if you are using Babel 7.x you may prefer to use a "project-wide configuration" (babel.config.js
) (docs) which "applies broadly, even allowing plugins and presets to easily apply to files in node_modules or in symlinked packages".
______
babel
3. Run Now running the babel
command as in your example should work:
$> babel ./src/myclass.js --out-file ./out/app.js
Alternatively, use a bundler like webpack, rollup, or browserify, with their respective babel plugin.
Solution 2 - Ecmascript 6
The exact answer using babel with nodejs (and using CLI):
Install babel and preset
npm install babel-cli babel-preset-es2015
Execute with npx
npx babel ./src/myclass.js --out-file ./out/app.js --presets babel-preset-es2015
Note
When babel-cli is globally installed could be not working. So this is my definitive solution
Solution 3 - Ecmascript 6
Babel doesn't usually target (or you don't usually want it to target) a specific standard, instead what it does is targeting the concrete browser versions you passed in somehow - explicitly like "targets": { "chrome": 70}
or implicitly in different ways, for example, like "targets": ">0.25%"
(market share) - in config files (package.json, .babelrc or babel.config.js). To make it possible, Babel gets the information about browser usage & features support from a number of other projects like browserlist.
Then it transforms your code as down as possible & needed in terms of a set of ECMA features whose emulative implementations are defined by presets (groups of plugins, let's say preset-env
). It finally comes to what can be run in the browsers you want your code to be run in.
For example, if you target browsers with market share > 15%, this code - let a = 5;
- will stay the same since these popular browsers are highly likely to be the latest versions of Chrome that perfectly support let
. On the other hand, if you indicate that you also want support for IE8, let a = 5;
becomes var a = 5;
since now Babel tries to make your code suitable for IE8 which knows nothing about let
. Well, you get the idea.
Also it is important to understand, that Babel isn't a silver bullet - it doesn't add anything beyond ECMAScript spec. For example, it doesn't provide polyfills for browser APIs (fetch
etc).
And if you gave no indications, then, as the documentation states:
> Sidenote, if no targets are specified, @babel/preset-env will > transform all ECMAScript 2015+ code by default. We don't recommend using preset-env this way because it doesn't take advantage of its ability to target specific browsers.