Setup | Running linting/tests | Writing tests | Internals
Before contributing, please read our code of conduct.
Contributions are always welcome, no matter how large or small.
- If you aren't just making a documentation change, you'll probably want to learn a bit about a few topics.
- ASTs (Abstract Syntax Tree): The Babel AST spec is a bit different from ESTree. The differences are listed here.
- This repository's
/doc
directory for notes on Babel's internals - Check out the Babel Plugin Handbook - core plugins are written the same way as any other plugin!
- Check out AST Explorer to learn more about ASTs or make your own plugin in the browser
- When you feel ready to finally jump into the babel source code a good start is to look out for issues which are labeled with help-wanted and/or beginner-friendly.
Feel free to check out the #discussion
/#development
channels on our slack. Some of us are always online to chat!
Note: Versions < 5.1.10
can't be built.
Babel is built for node 0.10 and up but we develop using node 6. Make sure you are on npm 3.
You can check this with node -v
and npm -v
.
$ git clone https://github.com/babel/babel
$ cd babel
$ make bootstrap
Then you can either run:
$ make build
to build Babel once or:
$ make watch
to have Babel build itself and incrementally build files on change.
You can access the built files for individual packages from packages/<package-name>/lib
.
If you wish to build a copy of Babel for distribution, then run:
$ make build-dist
You can run lint via:
# ~6 sec on a MacBook Pro (Mid 2015)
$ make lint
You can run eslint's autofix via:
$ make fix
You can run tests + lint for all packages (slow) via:
# ~46 sec on a MacBook Pro (Mid 2015)
$ make test
If you just want to run all tests:
# ~40 sec on a MacBook Pro (Mid 2015)
$ make test-only
Most likely you'll want to focus in on a specific issue.
To run tests for a specific package in packages, you can use the TEST_ONLY
environment variable:
$ TEST_ONLY=babel-cli make test
Use the TEST_GREP
variable to run a subset of tests by name:
$ TEST_GREP=transformation make test
To enable the node debugger added in v6.3.0, set the TEST_DEBUG
environment variable:
$ TEST_DEBUG=true make test
To test the code coverage, use:
$ make test-cov
Most packages in /packages
have a test
folder, however some tests might be in other packages or in /packages/babel-core
.
All the Babel plugins (and other packages) that have a /test/fixtures
are written in a similar way.
For example, in babel-plugin-transform-exponentiation-operator/test
:
-
There is an
index.js
file. It imports our test helper. (You don't have to worry about this). -
There can be multiple folders under
/fixtures
- There is an
options.json
file whose function is similar to a.babelrc
file, allowing you to pass in the plugins and settings you need for your tests. - For this test, we only need the relevant plugin, so it's just
{ "plugins": ["transform-exponentiation-operator"] }
. - If necessary, you can have an
options.json
with different options in each subfolder.
- There is an
-
In each subfolder, you can organize your directory structure by categories of tests. (Example: these folders can be named after the feature you are testing or can reference the issue number they fix)
-
Generally, there are two kinds of tests for plugins
- The first is a simple test of the input and output produced by running Babel on some code. We do this by creating an
actual.js
file and anexpected.js
file. - If you need to expect an error, you can ignore creating the
expected.js
file and pass a newthrows
key to theoptions.json
that contains the error string that is created. - The second and preferred type is a test that actually evaluates the produced code and asserts that certain properties are true or false. We do this by creating an
exec.js
file.
- The first is a simple test of the input and output produced by running Babel on some code. We do this by creating an
In an actual/expected test, you simply write out the code you want transformed in actual.js
.
// actual.js
2 ** 2;
and the expected output after transforming it with your options.json
in expected.js
.
// expected.js
Math.pow(2, 2);
In an exec.js
test, we run or check that the code actually does what it's supposed to do rather than just check the static output.
// exec.js
assert.equal(8, 2 ** 3);
assert.equal(24, 3 * 2 ** 3);
If you need to check for an error that is thrown you can add to the options.json
// options.json example
{
"plugins": [["transform-object-rest-spread", { "useBuiltIns": "invalidOption" }]],
"throws": "transform-object-rest-spread currently only accepts a boolean option for useBuiltIns (defaults to false)"
}
For both babel-plugin-x
and babylon
, you can easily generate an expected.js
/expected.json
automatically by just providing actual.js
and running the tests as you usually would.
// Example
- babylon
- test
- fixtures
- comments
- basic
- block-trailing-comment
- actual.js
- expected.json (will be generated if not created)
- AST spec (babylon/ast/spec.md)
- Versionning (doc/design/versioning.md)
- Monorepo (doc/design/monorepo.md)
- Compiler environment support (doc/design/compiler-environment-support.md)
- Compiler assumptions (doc/design/compiler-assumptions.md)