Babel Pocket Book — Uplatz
50 deep-dive flashcards • Single column • Presets & Plugins • TS & JSX • Polyfills & browserslist • Build & Performance • Interview Q&A
Readable snippets • Clear mental models • Production-oriented tips
1) What is Babel?
A JavaScript compiler that lets you use modern JS/TS/JSX today by transforming it to code that runs on your target environments (browsers/node).
npm i -D @babel/core @babel/cli
2) Presets vs Plugins
Plugins transform specific syntax (e.g., optional chaining). Presets are curated plugin bundles (e.g., @babel/preset-env
, @babel/preset-react
, @babel/preset-typescript
).
3) preset-env (the workhorse)
Compiles JS based on your targets
(or browserslist
). Adds only the transforms needed.
npm i -D @babel/preset-env
// babel.config.js
module.exports = { presets: [['@babel/preset-env',{ targets: ">0.25%, not dead" }]] };
4) Where do configs live?
Project-wide babel.config.js
(preferred for monorepos) or per-package .babelrc
/.babelrc.json
. CLI flags and package.json "babel"
field also work.
5) CLI basics
npx babel src --out-dir dist --extensions ".js,.jsx,.ts,.tsx" --source-maps
Use --copy-files
to copy non-compiled assets (e.g., CSS).
6) Modules handling
For bundlers (webpack/rollup/vite), set modules:false
to keep ES modules for tree-shaking. For Node or plain output, let Babel convert to CJS.
7) Proposal “syntax” vs “transform”
@babel/plugin-syntax-*
parses new syntax without changing output (for tooling). @babel/plugin-transform-*
compiles it to older JS.
8) Source maps
Generate maps for better debugging; bundlers can consume and re-map them.
npx babel src -d dist --source-maps inline
9) “Loose” mode
Some transforms have loose:true
for smaller/faster output with slightly different semantics. Use only if you understand trade-offs.
10) Bugfixes & shippedProposals
preset-env
options: bugfixes:true
applies Safari/V8 workarounds; shippedProposals:true
enables features that are in the spec but not yet widely implemented.
11) TypeScript with Babel
Babel strips types, but doesn’t type-check. Pair with tsc --noEmit
for checking.
npm i -D @babel/preset-typescript typescript
// babel.config.js
presets: [['@babel/preset-env'], '@babel/preset-typescript']
12) JSX & React
npm i -D @babel/preset-react
presets: [['@babel/preset-react',{ runtime:'automatic', development: process.env.NODE_ENV!=='production' }]]
“Automatic” runtime removes the need to import React for JSX in React 17+.
13) Next.js / CRA / Vite
These toolchains configure Babel for you. Customize via babel.config.js
or framework-specific hooks only when needed.
14) Polyfills: core-js & regenerator
Use @babel/preset-env
with useBuiltIns
and core-js@3
to inject polyfills based on targets.
npm i -D core-js regenerator-runtime
presets: [['@babel/preset-env',{ useBuiltIns:'usage', corejs:3 }]]
15) @babel/runtime & transform-runtime
Avoid duplicating helpers in every file; use runtime imports.
npm i -D @babel/plugin-transform-runtime @babel/runtime
plugins: [['@babel/plugin-transform-runtime',{ corejs:false }]]
16) browserslist integration
Define targets once in package.json
or .browserslistrc
; Babel, Autoprefixer, and others read it.
"browserslist": [">0.25%","not dead"]
17) Env-specific overrides
Different builds for dev/prod/test.
module.exports = {
presets:[['@babel/preset-env']],
env:{ test:{ presets:[['@babel/preset-env',{ targets:{ node:'current' }}]] } }
};
18) Per-file overrides
overrides:[{ test:/\.tsx?$/, presets:['@babel/preset-typescript'] }]
19) Ignore/only
Speed up builds by excluding generated or external code (e.g., node_modules
, dist
).
20) Decorators & class fields
These need coordinated plugins and options; align with your framework’s expectations (e.g., TypeScript legacy decorators).
npm i -D @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
plugins:[
['@babel/plugin-proposal-decorators',{ version:'legacy' }],
['@babel/plugin-proposal-class-properties',{ loose:true }]
]
21) Babel + Webpack
Use babel-loader
for JS/TS/JSX; set cacheDirectory:true
.
npm i -D babel-loader
// webpack.module.rules
{ test:/\.(t|j)sx?$/, exclude:/node_modules/, use:{ loader:'babel-loader', options:{ cacheDirectory:true }}}
22) Babel + Rollup
npm i -D @rollup/plugin-babel
// rollup.config.js
babel({ babelHelpers:'runtime', extensions:['.js','.jsx','.ts','.tsx'] })
23) Babel + Vite
Vite uses esbuild for TS/JS by default; add Babel only when you need Babel-only plugins (macros, special transforms).
24) Library builds
Publish dual ESM/CJS with exports
map. Don’t transpile user code; transpile your sources, ship types separately if using TS.
25) Node targets
For server code, target the running Node version to minimize transforms.
presets:[['@babel/preset-env',{ targets:{ node:'20' }, modules:'auto' }]]
26) babel-register (on-the-fly)
Useful for tools/tests. Not for production servers.
require('@babel/register')({ extensions:['.js','.ts','.tsx'] });
27) Caching
Use loader caches and persistent caches (webpack) to speed up rebuilds. Avoid dynamic config that busts cache every run.
28) Minification
Prefer Terser (via bundler). babel-minify
exists but is rarely needed in 2025.
29) tree-shaking & sideEffects
Keep ES modules, mark packages "sideEffects": false
(or specific files) to enable dead-code elimination.
30) Dynamic import & top-level await
Ensure bundler understands them; Babel parses via syntax plugins if needed.
npm i -D @babel/plugin-syntax-dynamic-import @babel/plugin-syntax-top-level-await
31) Programmatic API
const babel = require('@babel/core');
const out = babel.transformSync(code,{ presets:['@babel/preset-env'] });
32) Parsing/Traversing/Generating
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const t = require('@babel/types');
const generate = require('@babel/generator').default;
const ast = parser.parse(code,{ sourceType:'module', plugins:['typescript','jsx'] });
traverse(ast,{ Identifier(p){ if(p.node.name==='old') p.node.name='next'; }});
const { code: out } = generate(ast);
33) Write a tiny plugin
module.exports = function() {
return { visitor:{ Identifier(path){ if(path.node.name==='DEBUG'){ path.remove(); } } } };
};
34) Plugin ordering matters
Plugins run first-to-last; presets run last-to-first (inner first). Place syntax plugins before transforms that need them.
35) babel-plugin-macros
Compile-time helpers (e.g., linaria
, graphql.macro
) without custom config in each app.
npm i -D babel-plugin-macros
plugins:['babel-plugin-macros']
36) Jest + Babel
npm i -D babel-jest @babel/preset-env @babel/preset-react
// jest.config.js
transform:{ '^.+\\.[tj]sx?$':'babel-jest' }
37) ESLint & Type Checking
Babel doesn’t type-check; run tsc --noEmit
or vue-tsc
in CI; pair with ESLint for style/linting.
38) Common errors
“Support for the experimental syntax …” → missing syntax/transform plugin. “Unknown file extension .ts” → add preset-typescript or loader ext list.
39) Debugging transforms
Use --verbose
, BABEL_SHOW_CONFIG_FOR
, and babel --config-file
to inspect exactly which config applies.
40) Monorepos
Prefer root babel.config.js
(not .babelrc) so packages share config; use overrides
to tweak per-package.
41) Performance wins
Limit transforms, keep ES modules, cache aggressively, avoid transpiling node_modules
, and pick realistic targets (don’t target IE unless you must).
42) Using SWC/Esbuild with Babel
Many projects compile TS/JS with swc/esbuild for speed and add Babel for React macros or niche plugins.
43) Security & supply chain
Lock dependency versions, audit regularly, and avoid unknown plugins. Treat macros as compile-time code execution.
44) Shipping polyfills safely
Prefer usage
-based insertion with core-js@3
; avoid global pollution in libraries—document peer polyfills or use @babel/runtime-corejs3
.
45) Migrate from Babel 6 → 7+
Replace old preset names (env
), add @babel/*
scope, re-check decorators/class fields options, and update polyfill
strategy to core-js@3.
46) TS-only vs Babel+TS
If you don’t need JSX/many Babel plugins, tsc
emit or swc can be simpler. Use Babel when you need React/JSX, macros, or ecosystem plugins.
47) Publishing libraries
Ship ESM (and optionally CJS). Include sourcemaps. Don’t downlevel too far; let consumers decide targets. Document required polyfills.
48) Runtime helpers duplication
If bundle is bloated by helpers, add @babel/plugin-transform-runtime
with @babel/runtime
and set bundler to externalize it for libs.
49) Troubleshooting “regeneratorRuntime is not defined”
Include regenerator-runtime/runtime
or set useBuiltIns:'usage'
with core-js+regenerator; or use transform-runtime with regenerator:true
.
50) Interview Q&A — Practical
When preset-env? Always for cross-browser builds; it compiles based on browserslist.
Polyfill strategy? useBuiltIns:'usage'
+ core-js@3
to inject only what’s needed.
Why transform-runtime? Deduplicate helpers and avoid polluting globals, especially in libraries.
TS with Babel? Babel strips types—pair with tsc --noEmit
for type-checking.
Decorators gotchas? Align plugin options (legacy vs 2022). Mismatched settings cause runtime errors.