Frontend Development 13 min read

Understanding Babel: Core Functions, AST, Polyfills, and Presets

This article explains Babel's role as a fundamental JavaScript compiler, detailing its parsing‑transform‑printing pipeline, AST structure, core‑js polyfills, preset‑env configuration, and runtime helpers, providing frontend developers with a comprehensive guide to mastering Babel's ecosystem and optimizing bundle size.

ByteFE
ByteFE
ByteFE
Understanding Babel: Core Functions, AST, Polyfills, and Presets

When people first hear about Babel , they often think it is only used for API polyfills. In reality, Babel is the cornerstone of frontend engineering, encompassing a large family of concepts such as preset , plugin , and runtime , which can be intimidating for beginners.

What is Babel? Babel is a JavaScript compiler that receives input JS code, parses it into an abstract syntax tree (AST), transforms the AST, and finally prints the transformed code back to JavaScript.

The internal workflow consists of three steps:

Parsing: converting the input code into an AST.

Transforming: editing the AST.

Printing: generating the output code from the edited AST.

Babel’s source code is organized as a monorepo containing dozens of packages. The babel-core package implements the three steps, delegating parsing to babel-parser and printing to babel-generator . Traversal of the AST is performed by babel-traverse using a depth‑first algorithm, while babel-types provides the node‑type definitions needed to modify AST nodes.

Understanding the AST is essential. Using the AST Explorer with @babel/parser , the code const name = ['ka', 'song']; is parsed into a JSON‑formatted tree that represents the program structure.

Beyond the core compilation ability, Babel offers higher‑level features:

Polyfills (e.g., @babel/polyfill and @babel/preset-env ).

DSL transformations such as JSX.

Syntax transformations that downgrade newer syntax to code that runs in older environments.

The article focuses on polyfills and syntax transformation. The most common polyfill library is core-js , which provides implementations for ES2021 features, promises, symbols, iterators, and many WHATWG/W3C APIs. core-js itself is a monorepo with packages like core-js , core-js-pure , core-js-compat , core-js-builder , and core-js-bundle .

Example usage of core-js :

import 'core-js/features/array/from';
import 'core-js/features/array/flat';
import 'core-js/features/set';
import 'core-js/features/promise';

Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]
[1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5]
Promise.resolve(32).then(x => console.log(x)); // => 32

Using core-js-pure avoids polluting the global namespace:

import from from 'core-js-pure/features/array/from';
import flat from 'core-js-pure/features/array/flat';
import Set from 'core-js-pure/features/set';
import Promise from 'core-js-pure/features/promise';

from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3]
flat([1, [2, 3], [4, [5]]], 2); // => [1, 2, 3, 4, 5]
Promise.resolve(32).then(x => console.log(x)); // => 32

@babel/polyfill essentially bundles core-js and regenerator-runtime . Since Babel v7.4.0, @babel/polyfill is deprecated; developers should import core-js and regenerator-runtime directly.

@babel/preset-env enables on‑demand inclusion of core-js features, reducing bundle size. It works on two granularities:

Host‑environment granularity: bundles all features required by the browsers or Node versions specified in a browserslist configuration (e.g., "not IE 11" and "maintained node versions").

Usage granularity: with useBuiltIns: "usage" , only the features actually used in the source code are imported.

Example of useBuiltIns: "usage" :

var a = new Promise(); // a.js
var b = new Map(); // b.js

If the target environment lacks Promise and Map , Babel injects the corresponding core-js modules:

import "core-js/modules/es.promise";
var a = new Promise();
import "core-js/modules/es.map";
var b = new Map();

When the environment already supports those features, the original code is emitted unchanged.

To further reduce bundle size, Babel provides helper methods (e.g., _classCallCheck ) that can be shared via @babel/runtime . The @babel/plugin-transform-runtime plugin rewrites code to import these helpers from @babel/runtime instead of inlining them, and should be added as a devDependency, while @babel/runtime is a regular dependency.

Summary

The article walks through the Babel ecosystem from the low‑level core ( @babel/core , @babel/parser , @babel/traverse , @babel/types , @babel/generator ) that compiles JavaScript, through the middle layer of plugins that expose transformation APIs, up to the high‑level presets ( @babel/preset-* ) that developers use daily. Understanding these layers is essential for any frontend architect.

References:

[1] Babel repository: https://github.com/babel/babel/tree/main/packages

[2] AST Explorer: https://astexplorer.net/

[3] core‑js repository: https://github.com/zloirock/core-js/tree/master/packages

[4] Browserslist: https://github.com/browserslist/browserslist

[5] Babel v7.4.0 deprecation notice: https://babeljs.io/docs/en/babel-polyfill#docsNav

[6] babel‑plugin‑syntax‑decorators: https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-decorators

[7] Babel Playground: https://babeljs.io/repl#?browsers=&build=&builtIns=false&spec=false&loose=false&code_lz=MYGwhgzhAECCAO9oG8C-Q&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=script&lineWrap=true&presets=env&prettier=false&targets=&version=7.13.7&externalPlugins=babel-plugin-transform-regenerator%406.26.0

JavaScriptfrontend developmentASTBabelpolyfillCore-jsPreset
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.