Skip to content

BabelJs - 示例

BabelJS - 实践示例:一个图片轮播

Section titled “BabelJS - 实践示例:一个图片轮播”

让我们构建一个使用现代 JavaScript (ES2015+ 特性) 的简单项目,然后使用 BabelJS 将代码转译 (transpile) 为 ES5,以获得更广泛的兼容性。我们将创建一个自动图片轮播。本示例还将演示一个基本的 Gulp 设置,用于自动化 Babel 转译过程。我们将使用现代版本的 Babel(7+ 版本)包。

我们将使用 Gulp 作为任务运行器 (task runner) 来管理我们的构建过程 (build process)。首先,让我们设置项目。

创建一个新的项目文件夹(例如 babel-slider-example)并进入该文件夹。然后,初始化 npm:

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

现在,安装 Gulp 和必要的 Babel 及 Gulp 插件作为开发依赖 (development dependencies):

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

您的 package.json 文件现在将包含这些依赖。例如:

package.json 示例 (devDependencies 部分):

"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 // 具体版本会有所不同
}

在项目根目录创建 babel.config.json 文件,告诉 Babel 使用 @babel/preset-env 预设 (preset)。这个预设能够智能地将现代 JavaScript 转译为 ES5(默认情况下,或根据指定的目标环境):

babel.config.json:

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

在项目根目录创建 gulpfile.js 文件。这个文件将定义 Gulp 的任务。

gulpfile.js:

const gulp = require('gulp');
const babel = require('gulp-babel');
const connect = require('gulp-connect');
// Task to transpile JavaScript using Babel // 使用 Babel 转译 JavaScript 的任务
gulp.task('build-js', () => {
return gulp.src('src/**/*.js') // Get all .js files from src folder // 获取 src 文件夹下的所有 .js 文件
.pipe(babel()) // Transpile with Babel (uses babel.config.json) // 使用 Babel 转译 (使用 babel.config.json 配置)
.pipe(gulp.dest('dist/js')) // Output to dist/js folder // 输出到 dist/js 文件夹
.pipe(connect.reload()); // Reload browser if gulp-connect is running // 如果 gulp-connect 正在运行,则刷新浏览器
});
// Task to copy HTML files // 复制 HTML 文件的任务
gulp.task('copy-html', () => {
return gulp.src('src/*.html')
.pipe(gulp.dest('dist'))
.pipe(connect.reload());
});
// Task to copy CSS files (if any) // 复制 CSS 文件的任务 (如果有)
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 // 从 dist 文件夹提供文件服务
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'));

build-js 任务查找 src 文件夹中所有 .js 文件,通过 gulp-babel 管道处理(使用我们的 babel.config.json 配置),并将转译后的文件输出到 dist/js 文件夹。其他任务处理 HTML、CSS 和图片文件。

让我们设置以下项目结构:

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 // 主 HTML 文件
│ └── slider.js # Modern JavaScript for the slider // 现代 JavaScript 实现轮播
├── babel.config.json
├── gulpfile.js
└── package.json

确保您在 src/img/ 目录中放了一些占位图片(例如,image1.jpg、image2.jpg、image3.jpg)。

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 -->
<!-- 图片将由 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 (使用现代 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.`); // 找不到 id 为 '${containerId}' 的轮播容器
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);
});

这个 slider.js 文件使用了 ES6 的 class(类)、箭头函数 (arrow functions)、const/let 和模板字面量 (template literals)(在 alt 文本中隐式使用)。这些特性在旧版浏览器中可能无法工作,需要转译。

在项目根目录打开终端,运行默认的 Gulp 任务:

gulp

这个命令将执行以下操作:

  • 执行 build-js 任务:src/slider.js 将由 Babel 转译并保存到 dist/js/slider.js。
  • 执行 copy-html、copy-css、copy-images 任务。
  • 启动一个本地服务器,地址为 http://localhost:8080(或您配置的端口)。
  • 监听文件变化,并自动重新构建和刷新浏览器。

在浏览器中打开 http://localhost:8080。您应该能看到图片轮播正在工作,图片会自动切换。

如果您检查 dist/js/slider.js 文件,会发现它是 ES5 兼容版本的轮播代码。例如,class 语法会被转换为构造函数和原型方法。

dist/js/slider.js 的简化视图(实际输出可能更详细,包含辅助函数):

"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.")); // 找不到 id 为 ''.concat(containerId, '') 的轮播容器
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);
});

这个示例展示了一种常见的工作流程:使用现代 JavaScript 进行开发,并在构建过程(如 Gulp 或 Webpack)中使用 Babel 来确保最终代码与更广泛的浏览器兼容。这种方法允许开发者利用最新的语言特性,同时仍能支持其目标用户群。