
Why Babel is Needed
In development, we rarely interact with Babel directly, but Babel is indispensable for frontend development:
- We want to use
ES6+syntax,TypeScript, or developReactprojects, all of which rely onBabel. - Learning
Babelhelps us understand the transition from writing code to production deployment.
Babel is a toolchain primarily used to convert ECMAScript 2015+ code into backward-compatible versions for older browsers. Its functionalities include syntax transformation, source code transformation, and Polyfill.
Using Babel from the Command Line
Babel can be used independently without configuring build tools like webpack.
Install required packages:
- @babel/core: Core Babel code, must be installed.
- @babel/cli: Allows using Babel from the command line.
npm install @babel/cli @babel/core
Transform source code:
npx babel src --out-dir dist
src: source directory--out-dir: output folder
Using Plugins
To transform arrow functions:
npm install @babel/plugin-transform-arrow-functions -D
npx babel src --out-dir dist --plugins=@babel/plugin-transform-arrow-functions
Babel Presets
If there are many transformations, configuring one by one is cumbersome. We can use presets:
-
Install preset:
npm install @babel/preset-env -D -
Execute:
npx babel src --out-dir dist --presets=@babel/preset-env
Babel Internal Principles
How does Babel convert ES6/TypeScript/React code to ES5?
Babel can be seen as a compiler that transforms source code into a form the browser can understand. Workflow:
- Parsing
- Transformation
- Code Generation
Babel Compiler Execution Principle

Tokens array:

Generate AST (Abstract Syntax Tree) from tokens:

Each object represents a node. Traverse nodes, apply Babel plugins, generate new AST, then output code.
babel-loader
In practice, we often use Babel with build tools, e.g., webpack:
{
test: /\.js$/,
use: {
loader: "babel-loader",
options: {
plugins: [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping"
],
presets: ["@babel/preset-env"]
}
}
}
Setting Target Browsers with browserslist
Babel needs to know which browsers to target.
- Use
browserslistortargetoption
use: {
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", { targets: ["chrome 88"] }]
],
plugins: [
"@babel/plugin-transform-arrow-functions",
"@babel/plugin-transform-block-scoping"
]
}
}
Stage-X Presets
-
TC39: Technical Committee 39, part of ECMA standardizing JavaScript evolution.
-
Features are added in stages:
- Stage 0: Strawman
- Stage 1: Proposal
- Stage 2: Draft
- Stage 3: Candidate
- Stage 4: Finished
Babel Stage-X Configuration
Before Babel7 (e.g., Babel6), we used babel-preset-stage-x, now deprecated in favor of preset-env:
module.exports = {
preset: ["stage-0"]
}
Babel Configuration Files
Two types of config files:
babel.config.json(or .js, .cjs, .mjs).babelrc.json(or .babelrc, .js, .cjs, .mjs)
.babelrc.json was popular early, but babel.config.json is recommended for monorepos.
module.exports = {
presets: [["@babel/preset-env"]],
}
Understanding Polyfills
- Syntax features like
Promise,Generator,Symbolmay not be supported in some browsers. - Use
polyfillto patch.
Using Polyfills
Install:
npm install core-js regenerator-runtime --save
Exclude node_modules in loader:
{
test: '/\.m?js$/',
exclude: /node-modules/,
use: 'babel-loader',
}
Configure preset-env:
useBuiltIns: how polyfills are usedcorejs: version (usually 3.x)proposals: include stage proposals if true
module.exports = {
presets: [
["@babel/preset-env", {
useBuiltIns: "usage",
corejs: 3
}],
["@babel/preset-react"]
]
}
Plugin-transform-runtime
-
Avoid global pollution when creating a library.
-
Install:
npm install @babel/plugin-transform-runtime -D -
Configure:
plugins: [["@babel/plugin-transform-runtime", { corejs: 3 }]]
JSX Support
-
Reactusesjsx. Transform with preset:npm install @babel/preset-react -D
TypeScript Compilation
Using ts-loader
npm install ts-loader -D
{
test: /\.ts$/,
exclude: /node_modules/,
use: "babel-loader"
}
Using babel-loader
- Supports TypeScript via
@babel/preset-typescript.
module.exports = {
presets: [
["@babel/preset-env", { useBuiltIns: "usage", corejs: 3 }],
["@babel/preset-react"],
["@babel/preset-typescript"]
]
}
ts-loader vs babel-loader
ts-loader: only compiles TS -> JS, cannot add polyfills.babel-loader: compiles TS -> JS, can add polyfills, does not check types.
Best Practice
Use Babel for code transformation and tsc for type checking.

