We talk about JavaScript. Each month in Warsaw, Poland.
@ Shedul.com, Warsaw
Full stack developer. Like challenges, JavaScript and Python.
Privately is passionate about triathlon.
"Do. Or do not. There is no try" (c) Yoda
Babel is a JavaScript transpiler.
Sure, it can convert ES8 code to ES5 ... but not only !
It is essentially a platform for developing future EcmaScript language and tooling.
Asany compiler, Babel consists of several parts:
babylon is the Babel's tokenizerbabel-generator)
> npm install babel-cli
> babel inscript.js -o outscript.js // transpile
> babel indir -o outfile.js // transpile & concatenate
> babel --watch indir -o outscript.js // watch & transpile & concatenate
Many other options are allowed.
Often used in prepublish scripts for packages targeted to Node runtime.
Watch mode is useful when working on multiple "ad-hoc" scripts
> npm install babel-node
> babel-node es8-script.js
It is like a node with babel inside. Mostly for one-off scripts ...
// entry-point.js - still have to use require()
require('babel-register');
require('./es8-script.js');
// es8-script.js - magic happens here
console.log('123'.padStart(6, ' '));
Babel intercepts require() calls and transpiles modules on the fly. Transpiled modules are cached on disk. This mechanism does not work in a browser.
import babel from 'babel-core';
const {
code, // resulting code
map, // source map
ast // resulting AST (abstract syntaxt tree)
} = babel.transform(sourceCode, options);
How AST looks like.
babel.transformFile(filename, options, callback);
const { code, map, ast } =
babel.transformFileSync(filename, options);
const { code, map, ast } =
babel.transformFromAST(ast, code, options);
By default Babel.js does nothing ...
... because all the power is in plugins !
... and before using, one should configure them !
.babelrc - preferred waypackage.jsonbabel-register
{
"presets": ["env", "react"],
"env": {
"production": {
// strip assertions & minify
"plugins": ["babel-plugin-unassert"],
"presets": ["babili", "env", "react"]
}
},
...
}
.babelrc is a JSON5 (user-friendly JSON). Babel 7 should
support configuration in JavaScript - .babelrc.js
Plugins can have options.
[ "env", { "targets": { "node": "current" } },
Order of plugins and presets does matter ! Plugins runs firstly in left-to-right order in the configuration, presets run after plugins in the right-to-left order.
/src
// top-level .babelrc is used here
...
/legacy
...
.babelrc // this file is used for legacy subtree
// which e.g. may have less transforms
...
.babelrc
If there is more than one .babelrc file, only the "closest" one (up the folder tree) is used !
Helps for projects with several distinct parts (e.g. Express app with client and server parts, legacy subsystem, React code, etc.)
{
"name": "some-package",
"babel": { // top-level key only
...
},
...
}
Options from .babelrc have priority over those from
package.json.
require('babel-register')({
plugins: ['env'],
...
ignore: /^ignore-me\/.*\.js$/,
only: /^compile-only-me\/.*\.js$/,
extensions: ['.js', '.jsx'],
cache: true
});
Plugin do code transformations !
Every Babel.js transformation in Babel.js is done by some plugin !
Preset is a name for group of plugins used simultaneously.
env takes environment spec and uses corresponding language language spec pluginsstage-X enables experimental language features from stage Xreact enables parsing and transpiling of JSX filesflow enables parsing and removal of Flow annotations from resulting codeTakes target environment specification and the
current language standard version to determine plugins needed. We can in principle stop unsing
es20XX presets
"plugins": [
["env", {
"targets": {
"browsers": ["ie > 10", "> 1%"],
"node": "6"
}
}]
]
Everyone can create custom presets !
They help enforce consistent environments.
Essentially, you need a NPM package with 2 files - package.json and index.js.
{
"name": "@your-scope/babel-preset-your-preset",
"version": "1.2.3",
...
"dependencies": {
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.23.0",
...
}
}
module.exports = {
presets: [
['env', {
targets: {
browsers: ['> 1%']
}
}],
'react'
]
};
Yesterday there were more than 1700 packages for Babel
babel-eslint)babili)istanbul)babel-plugin-unassert - removes assertions from source code
babel-plugin-react-intl - extracts literals for translation from React projects
babel-plugin-istanbul - add Instanbul coverage code
remove debugger statements
export default function ({ path, source }, { jscodeshift: j }, options) {
return j(source).find(j.DebuggerStatement).forEach(path => {
j(path).remove();
}).toSource();
};