Introduction to Babel
Introduction
Babel is a JavaScript transpiler that converts not only ECMAScript 2015+ but also JS extensions like JSX, Flow, TypeScript, and other proposals into JavaScript code that can run in any browser or JavaScript environment.
(Not so) Simple Example: Finding non declared variables
Clone the repo ULL-ESIT-PL/babel-learning.
The problem
We want to write a Babel plugin that checks for non declared variables in a JavaScript program.
Babel plugins are JavaScript functions that take an Abstract Syntax Tree (AST) as input and return a modified AST. Therefore we intervene in the âTransform ASTâ stage of the compiler pipeline.
You have an example in the directory src/scope/non-declared
â non-declared git:(main) â pwd -P
/Users/casianorodriguezleon/campus-virtual/2324/learning/babel-learning/src/scope/non-declared
Consider an input.js like this:
let n = 4;
let f = m => m + n; // m is declared
m = 9; // m is not declared
n = n * m;
where n
is declared but the m
at lines 3 and 4 is not declared.
The transpiling with our plugin should produce an output like this:
â non-declared git:(main) npx babel input.js
Searching for variable "m"
m at 2 is declared.
m at 3 is not declared.
m at 4 is not declared.
This is achieved with the plugin nondeclared.mjs
â non-declared git:(main) â cat nondeclared.mjs
export default function () {
return {
visitor: {
Program: {
enter(path, state) {
let varName = state.opts.varName;
console.log(`Searching for variable "${varName}"`);
state.nonDeclared = new Map();
state.Declared = new Map();
},
exit(path, state) {
state.Declared.forEach((value, key) => { console.log(key, value); });
state.nonDeclared.forEach((value, key) => { console.log(key, value); });
process.exit(0);
}
},
Identifier(path, state) {
let varName = state.opts.varName;
let node = path.node;
if (node.name !== varName) { return; }
if (!path.scope.hasBinding(varName)) {
state.nonDeclared.set(`${varName} at ${node.loc.start.line}`, `is not declared.`)
return
}
state.Declared.set(`${varName} at ${node.loc.start.line}`, `is declared.`);
return;
},
}
};
}
State as a way to set context for the visit
Babel plugins can have functions that are run before or after plugins. They can be used for setup or cleanup/analysis purposes. See this tutorial. In this example:
- In the
enter
method ofProgram
, we initialize some state. - We have other visitors (like
Identifier
) that perform operations and potentially modify the state. - The
exit
method ofProgram
is called after all nodes have been visited and processed.
Configuring Babel and passing options to the plugin
The value of the variable state.opts.varName
is set as an option to the plugin via the configuration file
src/scope/non-declared/babel.config.js
â non-declared git:(main) â cat babel.config.js
module.exports = function(api) {
api.cache(true); // You are instructing Babel to cache the computed configuration and
// reuse it on subsequent builds.
const defaultEnv = {
plugins: [
["./nondeclared.mjs", { "varName": "m" }]
]
};
const customEnv = {
plugins: [
["./nondeclared.mjs", { "varName": "n" }]
]
};
return {
env: {
development: defaultEnv,
custom: customEnv
}
};
};
and specified later in the command line via the --env-name
option:
â non-declared git:(main) â non-declared git:(main) npx babel input.js --env-name custom
Searching for variable "n"
n at 1 is declared.
n at 2 is declared.
n at 4 is declared.
You can also use the BABEL_ENV
or NODE_ENV
environment variables to specify the environment:
â non-declared git:(main) BABEL_ENV=custom npx babel input.js
Searching for variable "n"
n at 1 is declared.
n at 2 is declared.
n at 4 is declared.
References
-
Our notes YATBABEL: Yet Another Tutorial on Babel
-
See the Svelte maintainer Tan Liu Hau (éç«è±Ș) article âCreating custom JavaScript syntax with Babelâ (September 25, 2019) available at https://lihautan.com/creating-custom-javascript-syntax-with-babel
-
Babel ast-explorer: https://lihautan.com/babel-ast-explorer/
-
Step-by-step guide for writing a custom babel transformation September 12, 2019
-
Babel macros by Tan Liu Hau
-
I Can Babel Macros (and So Can You!) by Shawn âswyxâ Wang in JSConf Hawaii 2019 (Growing a Language)
-
Learning Babel Macros: ULL-ESIT-PL/learning-babel-macros by Casiano
-
babel-plugin-macros Usage for macros authors. A tutorial on how to write Babel macros by Kent C. Dodds
-
Babel flow pragma bug not finished
-
My PL notes on Babel are here: https://ull-pl.vercel.app/topics/tree-transformations/babel
-
StackOverflow: How to create a babel plugin for internal use
-
See this introduction by Matt Zeunert and the associated GitHub repository for a simple example of how to create a Babel plugin.
-
Babel Handbook at jamiebuilds/babel-handbook This document covers how to create Babel plugins.
-
Awesome Babel A list of awesome Babel plugins, presets, etc.
-
Babel plugin Remove debugger transform. This plugin removes all
debugger;
statements -
A boilerplate monorepo for people writing babel plugins in normal plugin form as well as babel-plugin-macros form by Shawn âswyxâ Wang
-
JavaScript engines - how do they even? by Franziska Hinkelmann from the V8 Team. Youtubes. JSConf EU 2017
-
Parsing JavaScript - better lazy than eager? by Marja HölttÀ from the V8 Team. JSConf EU 2017
-
Parsing Javascript - Programming Languages a non maintained Udacity course. 2012. The Youtube list of videos for this course
-
ECMA TC39, TC53 presentations at Youtube
-
TC39: From the Proposal to ECMAScript, Step by Step. Romulo Cintra. Feb 2024. Youtube [Slides}(https://es.slideshare.net/slideshow/from-the-proposal-to-ecmascript-step-by-step/264286515)
Same contents and title but in Porto: https://youtu.be/ZheFIz4FhXo?si=ZQqgUWdEm5EU6iAj TC39 â From the proposal to ECMAScript - Step by Step - Romulo Cintra - Fest.dev Porto, 2023
-
So how does Babel even work? by Henry Zhu. 2017. Youtube
-
On BabelJS by James Kyle. 2016. Youtube. (Slides)
-
Nicoloâs talk
@babel/howto
at HolyJS in Youtube: https://youtu.be/UeVq_U5obnE?si=Vl_A49__5zgITvjx- See the associated repo at GitHub: https://github.com/nicolo-ribaudo/conf-holyjs-moscow-2019,
- Nicolo slides
- The plugin babel-plugin-transform-optional-chaining at GitHub Babel repo and the way it is used
- Web site of the HolyJS 2019 conference: https://holyjs.ru/en/archive/2019%20Moscow/
- babel-plugin-tester
-
Babel: Beyond the Basics. Sebastian McKenzie, Creator of Babel. 2015. Youtube. Slides
-
Google slides of the presentation at ĂLTIMOS AVANCES EN INFORMĂTICA 2004 XXVIII ed. âFunction Expressions on the Left Side of Assignmentsâ