Skip to content

BabelJs - Project setup using Babel 6

This chapter guides you through setting up a modern JavaScript project using Babel (version 7 and newer). We’ll create a simple Node.js project and use a local development server to test our transpiled JavaScript. The focus is on the current best practices for Babel configuration.

First, create a new directory for your project and navigate into it. Then, initialize it as a Node.js project using npm, which will create a package.json file.

mkdir my-babel-project
cd my-babel-project
npm init -y

The -y flag accepts all default options for npm init.

Your package.json will look something like this initially:

{
"name": "my-babel-project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

We need to install the core Babel packages as development dependencies. For a typical setup, these include:

  • @babel/core: The main Babel engine.
  • @babel/cli: The command-line interface to run Babel.
  • @babel/preset-env: A smart preset that allows you to use the latest JavaScript without needing to micromanage syntax transforms. It automatically determines the Babel plugins and polyfills needed based on your targeted environments.
npm install --save-dev @babel/core @babel/cli @babel/preset-env

After installation, your package.json’s devDependencies section will be updated:

"devDependencies": {
"@babel/cli": "^7.x.x",
"@babel/core": "^7.x.x",
"@babel/preset-env": "^7.x.x"
// Exact versions will depend on the latest releases
}

Create a Babel configuration file in your project’s root directory. The most common name is babel.config.json (or babel.config.js for more complex configurations).

babel.config.json:

{
"presets": ["@babel/preset-env"]
}

This configuration tells Babel to use the @babel/preset-env. By default, this preset will transpile all ECMAScript 2015+ syntax to be ES5 compatible.

To make transpiling easier, let’s add a script to our package.json. This script will take files from a src directory, transpile them, and output them to a dist (distribution) directory.

Modify the scripts section in package.json:

"scripts": {
"build": "babel src -d dist",
"test": "echo \"Error: no test specified\" && exit 1"
}

The babel src -d dist command tells Babel CLI to take all JavaScript files in the src directory, transpile them according to babel.config.json, and place the output files in the dist directory, maintaining the original file structure.

Create a src directory in your project root. Inside src, create a JavaScript file, for example, main.js, with some modern JavaScript syntax.

src/main.js:

class Student {
constructor(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
displayInfo() {
console.log(`Student: ${this.fullName}, Age: ${this.age}`);
}
}
const student1 = new Student("Jane", "Doe", 22);
student1.displayInfo();
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
console.log('Doubled numbers:', doubled);

Now, you can run the build script from your terminal:

npm run build

This will execute the babel src -d dist command. After it completes, you’ll find a dist directory in your project root containing the transpiled main.js.

The dist/main.js file will contain ES5-compatible code. For example, the class syntax will be transformed into constructor functions and prototypes, and arrow functions will be converted to regular functions.

Content of dist/main.js (simplified):

"use strict";
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
var Student = /*#__PURE__*/function () {
function Student(firstName, lastName, age) {
_classCallCheck(this, Student);
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
_createClass(Student, [{
key: "fullName",
get: function get() {
return "".concat(this.firstName, " ").concat(this.lastName);
}
}, {
key: "displayInfo",
value: function displayInfo() {
console.log("Student: ".concat(this.fullName, ", Age: ").concat(this.age));
}
}]);
return Student;
}();
var student1 = new Student("Jane", "Doe", 22);
student1.displayInfo();
var numbers = [1, 2, 3];
var doubled = numbers.map(function (num) {
return num * 2;
});
console.log('Doubled numbers:', doubled);

7. Testing with a Simple HTML File and Dev Server (Optional)

Section titled “7. Testing with a Simple HTML File and Dev Server (Optional)”

To test the transpiled code in a browser, you can create a simple index.html file in your dist directory (or serve it from there) and install a simple development server like lite-server.

npm install --save-dev lite-server

Add a start script to package.json:

"scripts": {
"build": "babel src -d dist",
"start": "lite-server --baseDir dist",
"test": "echo \"Error: no test specified\" && exit 1"
}

Create dist/index.html:

<!DOCTYPE html>
<html>
<head>
<title>Babel Test</title>
</head>
<body>
<h1>Check the console for output!</h1>
<script src="main.js"></script>
</body>
</html>

Now, first build your code, then start the server:

npm run build
npm start

lite-server will open dist/index.html in your default browser. Open the developer console to see the output from main.js:

Student: Jane Doe, Age: 22
Doubled numbers: [ 2, 4, 6 ]

This setup provides a basic but effective way to use Babel in your projects. For more complex applications, you’d typically integrate Babel with a module bundler like Webpack or Rollup, which we’ll cover in another chapter.

Further Considerations: @babel/preset-env can be further configured to target specific browsers or Node.js versions, optimizing the output and polyfill usage. See the Babel documentation for more on targets and useBuiltIns options.