Skip to content

BabelJs - Examples

BabelJS - Practical Example: An Image Slider

Section titled “BabelJS - Practical Example: An Image Slider”

Let’s build a simple project using modern JavaScript (ES2015+ features) and then use BabelJS to transpile the code to ES5 for broader compatibility. We’ll create an automatic image slider. This example will also demonstrate a basic Gulp setup for automating the Babel transpilation process. We will be using modern Babel (version 7+) packages.

We will use Gulp as a task runner to manage our build process. Let’s start by setting up the project.

1. Initialize Project and Install Dependencies

Section titled “1. Initialize Project and Install Dependencies”

Create a new project folder (e.g., babel-slider-example) and navigate into it. Then, initialize npm:

mkdir babel-slider-example
cd babel-slider-example
npm init -y

Now, install Gulp and the necessary Babel and Gulp plugins as development dependencies:

npm install --save-dev gulp gulp-babel @babel/core @babel/preset-env gulp-connect

Your package.json will now include these dependencies. For example:

Sample package.json (devDependencies section):

"devDependencies": {
"@babel/core": "^7.x.x",
"@babel/preset-env": "^7.x.x",
"gulp": "^4.x.x",
"gulp-babel": "^8.x.x",
"gulp-connect": "^5.x.x"
// Exact versions will vary
}

Create a babel.config.json file in your project root to tell Babel to use the @babel/preset-env preset, which intelligently transpiles modern JavaScript to ES5 (by default, or based on specified targets):

babel.config.json:

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

Create a gulpfile.js in your project root. This file will define tasks for Gulp.

gulpfile.js:

const gulp = require('gulp');
const babel = require('gulp-babel');
const connect = require('gulp-connect');
// Task to transpile JavaScript using Babel
gulp.task('build-js', () => {
return gulp.src('src/**/*.js') // Get all .js files from src folder
.pipe(babel()) // Transpile with Babel (uses babel.config.json)
.pipe(gulp.dest('dist/js')) // Output to dist/js folder
.pipe(connect.reload()); // Reload browser if gulp-connect is running
});
// Task to copy HTML files
gulp.task('copy-html', () => {
return gulp.src('src/*.html')
.pipe(gulp.dest('dist'))
.pipe(connect.reload());
});
// Task to copy CSS files (if any)
gulp.task('copy-css', () => {
return gulp.src('src/css/*.css')
.pipe(gulp.dest('dist/css'))
.pipe(connect.reload());
});
// Task to copy images
gulp.task('copy-images', () => {
return gulp.src('src/img/*')
.pipe(gulp.dest('dist/img'))
.pipe(connect.reload());
});
// Task to watch for changes and rebuild
gulp.task('watch', () => {
gulp.watch('src/**/*.js', gulp.series('build-js'));
gulp.watch('src/*.html', gulp.series('copy-html'));
gulp.watch('src/css/*.css', gulp.series('copy-css'));
gulp.watch('src/img/*', gulp.series('copy-images'));
});
// Task to start a local development server
gulp.task('serve', () => {
connect.server({
root: 'dist', // Serve files from the dist folder
livereload: true,
port: 8080
});
});
// Default task: build all assets and start watching and serving
gulp.task('default', gulp.series(
gulp.parallel('copy-html', 'copy-css', 'copy-images', 'build-js'),
gulp.parallel('serve', 'watch')
));
// Build task for production (without serve and watch)
gulp.task('build', gulp.parallel('copy-html', 'copy-css', 'copy-images', 'build-js'));

The build-js task finds all .js files in the src folder, pipes them through gulp-babel (which uses our babel.config.json), and outputs the transpiled files to the dist/js folder. Other tasks handle HTML, CSS, and images.

Let’s set up the following project structure:

babel-slider-example/
├── dist/ # Output folder for compiled/copied assets
├── node_modules/
├── src/
│ ├── css/
│ │ └── style.css # Styles for the slider
│ ├── img/
│ │ ├── image1.jpg # Slider images
│ │ ├── image2.jpg
│ │ └── image3.jpg
│ ├── index.html # Main HTML file
│ └── slider.js # Modern JavaScript for the slider
├── babel.config.json
├── gulpfile.js
└── package.json

Ensure you have some placeholder images (e.g., image1.jpg, image2.jpg, image3.jpg) in the src/img/ directory.

src/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Babel Image Slider</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Auto Image Slider</h1>
<div id="slider-container">
<!-- Images will be loaded here by JavaScript -->
</div>
<script src="js/slider.js"></script>
</body>
</html>

src/css/style.css:

body {
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
}
#slider-container {
width: 500px;
height: 300px;
border: 2px solid #ccc;
overflow: hidden; /* Important for hiding non-active slides */
position: relative; /* For absolute positioning of slides */
}
.slide {
width: 100%;
height: 100%;
position: absolute;
opacity: 0;
transition: opacity 1s ease-in-out;
}
.slide.active {
opacity: 1;
}
.slide img {
width: 100%;
height: 100%;
object-fit: cover;
}

src/slider.js (using modern JavaScript):

class ImageSlider {
constructor(containerId, images, interval = 3000) {
this.container = document.getElementById(containerId);
this.images = images; // Array of image paths
this.interval = interval;
this.currentIndex = 0;
this.slides = [];
if (!this.container) {
console.error(`Slider container with id '${containerId}' not found.`);
return;
}
this.init();
}
init() {
this.images.forEach((imgPath, index) => {
const slideDiv = document.createElement('div');
slideDiv.classList.add('slide');
if (index === 0) {
slideDiv.classList.add('active');
}
const imgElement = document.createElement('img');
imgElement.src = imgPath;
imgElement.alt = `Slide ${index + 1}`;
slideDiv.appendChild(imgElement);
this.container.appendChild(slideDiv);
this.slides.push(slideDiv);
});
this.start();
}
nextSlide = () => {
this.slides[this.currentIndex].classList.remove('active');
this.currentIndex = (this.currentIndex + 1) % this.images.length;
this.slides[this.currentIndex].classList.add('active');
}
start() {
setInterval(this.nextSlide, this.interval);
}
}
// Initialize the slider
document.addEventListener('DOMContentLoaded', () => {
const imagePaths = [
'img/image1.jpg',
'img/image2.jpg',
'img/image3.jpg'
// Add more image paths if you have more images
];
new ImageSlider('slider-container', imagePaths, 3000);
});

This slider.js uses ES6 classes, arrow functions, const/let, and template literals (implicitly in alt text). These features might not work in older browsers without transpilation.

Open your terminal in the project root and run the default Gulp task:

gulp

This command will:

  • Execute the build-js task: src/slider.js will be transpiled by Babel and saved to dist/js/slider.js.
  • Execute copy-html, copy-css, copy-images tasks.
  • Start a local server at http://localhost:8080 (or the port you configured).
  • Watch for file changes and automatically rebuild and reload the browser.

Open http://localhost:8080 in your browser. You should see the image slider working, with images changing automatically.

If you inspect dist/js/slider.js, you’ll find the ES5-compatible version of your slider code. For example, the class syntax would be transformed into constructor functions and prototype methods.

Simplified view of dist/js/slider.js (actual output might be more verbose with helpers):

"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; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var ImageSlider = /*#__PURE__*/function () {
function ImageSlider(containerId, images) {
var _this = this;
var interval = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3000;
_classCallCheck(this, ImageSlider);
_defineProperty(this, "nextSlide", function () {
_this.slides[_this.currentIndex].classList.remove('active');
_this.currentIndex = (_this.currentIndex + 1) % _this.images.length;
_this.slides[_this.currentIndex].classList.add('active');
});
this.container = document.getElementById(containerId);
this.images = images; // Array of image paths
this.interval = interval;
this.currentIndex = 0;
this.slides = [];
if (!this.container) {
console.error("Slider container with id '".concat(containerId, "' not found."));
return;
}
this.init();
}
_createClass(ImageSlider, [{
key: "init",
value: function init() {
var _this2 = this;
this.images.forEach(function (imgPath, index) {
var slideDiv = document.createElement('div');
slideDiv.classList.add('slide');
if (index === 0) {
slideDiv.classList.add('active');
}
var imgElement = document.createElement('img');
imgElement.src = imgPath;
imgElement.alt = "Slide ".concat(index + 1);
slideDiv.appendChild(imgElement);
_this2.container.appendChild(slideDiv);
_this2.slides.push(slideDiv);
});
this.start();
}
}, {
key: "start",
value: function start() {
setInterval(this.nextSlide, this.interval);
}
}]);
return ImageSlider;
}(); // Initialize the slider
document.addEventListener('DOMContentLoaded', function () {
var imagePaths = ['img/image1.jpg', 'img/image2.jpg', 'img/image3.jpg' // Add more image paths if you have more images
];
new ImageSlider('slider-container', imagePaths, 3000);
});

This example demonstrates a common workflow: developing with modern JavaScript and using Babel within a build process (like Gulp or Webpack) to ensure the final code is compatible with a wider range of browsers. This approach allows developers to benefit from the latest language features while still supporting their target user base.