首页 >web前端 >js教程 >使用Babel&Gulp将ES6模块转换为AMD和COMPORJS

使用Babel&Gulp将ES6模块转换为AMD和COMPORJS

William Shakespeare
William Shakespeare原创
2025-02-19 12:46:13713浏览

Transpiling ES6 Modules to AMD & CommonJS Using Babel & Gulp

核心要点

  • ECMAScript 6 (ES6) 对 JavaScript 做出了大量改进,以更好地适应其当前的使用规模,包括能够以模块的形式加载应用程序的不同部分。但是,并非所有浏览器都已实现所有 ES6 功能,这就是 Babel 和 Traceur 等转译器发挥作用的地方。
  • Babel 和 Gulp 可用于将 ES6 模块转译为 CommonJS 或 AMD,使它们能够被当今的浏览器读取。此过程涉及使用 Babel 的 Gulp 任务将模块转换为现有模块系统之一,然后将应用程序打包为单个文件供浏览器使用。
  • CommonJS 是一个同步模块系统,由 Node.js 使用,它使用 require 函数加载模块,并使用模块对象的 exports 属性导出它们。将 ES6 模块转换为 CommonJS 涉及结合使用 Babel、Browserify 和 Gulp。
  • 异步模块定义 (AMD) 系统允许并行加载多个依赖模块。要将 ES6 模块转换为 AMD,我们使用 Babel、RequireJS 和 Gulp。然后可以直接在 index.html 页面上引用最终脚本并在浏览器中查看。

ECMAScript 6(又名 ECMAScript 2015 或 ES6),下一版 JavaScript 的规范已获批准,浏览器厂商正在努力实施它。与以前的 ECMAScript 版本不同,ES6 对语言做出了巨大的改变,使其能够很好地适应当今的使用规模。Sitepoint 有多篇文章介绍了这些功能。

尽管浏览器尚未实现所有功能,但我们仍然可以在开发过程中利用 ES6,并在交付应用程序之前将其转换为浏览器可以理解的版本。Babel 和 Traceur 是为此目的使用的两种领先的转译器。Microsoft 的 JavaScript 类型超集 TypeScript 也可以用作 ES6 转译器。

在我之前的一篇文章中,我介绍了如何使用 ES6 来编写 Angular 1.x 应用程序。在那篇文章中,我使用了 Traceur 的即时转译器来运行应用程序。虽然它有效,但最好事先进行转译,并减少浏览器中需要完成的工作量。在本文中,我们将看到如何将相同的示例应用程序转译为 ES5,并将模块转换为 CommonJS 或 AMD,使用 Babel 使其能够在当今的浏览器上运行。尽管示例基于 Angular,但转译技术可用于任何有效的 ES6 代码。

与往常一样,您可以在我们的 GitHub 仓库中找到本文的配套代码。

模块的重要性

在用于编写大型应用程序的任何语言中,一个关键功能是能够以模块的形式加载应用程序的不同部分。模块不仅有助于使代码更简洁,而且还在减少全局作用域的使用方面发挥作用。除非其他模块显式加载它,否则模块的内容不会提供给任何其他模块。

模块的重要性不仅限于应用程序。即使是大型 JavaScript 库也可以利用模块系统将它们的对象导出为模块,并且使用这些库的应用程序可以根据需要导入这些模块。Angular 2 和 Aurelia 已开始使用此功能。

如果您想快速了解如何在 ES6 中使用模块,请阅读:理解 ES6 模块

关于示例应用程序

我们的示例应用程序的主题是虚拟书架。它包含以下页面:

  1. 首页:显示可以标记为已读或移动到存档的活动书籍列表。
  2. 添加书籍页面:通过接受书籍标题和作者姓名来向书架添加新书籍。它不允许重复标题。
  3. 存档页面:列出所有存档的书籍。

该应用程序使用 AngularJS 1.3 和 ES6 构建。如果您查看 app 文件夹中的任何文件,您将看到用于从当前模块导出对象以及从其他模块导入对象的关键字 export 和 import。现在,我们的工作是使用 Babel 的 Gulp 任务将这些模块转换为现有模块系统之一。

但我没有使用 Angular。我只想将 ES6 模块转换为 CommonJS/AMD

别担心!我们已经为您准备好了。只需少量调整,下面演示的配方即可用于任何涉及 ES6 模块的项目。Angular 在这里并不重要。

转换为 CommonJS

CommonJS 是由 CommonJS 组定义的模块系统。它是一个同步模块系统,其中使用 require 函数加载模块,并使用模块对象的 exports 属性导出模块。模块对象默认情况下应在所有模块中可用。

Node.js 使用此模块系统,因此它本机定义模块对象并将其提供给您的应用程序。由于浏览器没有定义此对象,因此我们需要使用名为 Browserify 的实用程序来填补空白。

在开始之前,我们还需要安装一些 npm 包。这将使我们能够结合使用 Babel 和 Browserify 与 Gulp,将我们的 ES6 模块转换为常见的模块格式之一,并将应用程序打包为单个文件供浏览器使用。

  • gulp-babel — 将 ES6 代码转换为普通的 ES5
  • Browserify — 允许您在浏览器中 require('modules'),方法是捆绑所有依赖项
  • vinyl-source-stream — 直接处理 Browserify 模块,避免需要 gulp-browserify 包装器
  • vinyl-buffer — 将流转换为缓冲区(对于不支持流的 gulp-uglify 来说是必要的)
  • gulp-uglify — 压缩文件
  • del — 允许您删除文件和文件夹
  • gulp-rename — 一个允许您重命名文件的插件

您可以通过键入以下内容来获取所有这些:

<code>npm install gulp-babel browserify gulp-browserify vinyl-source-stream vinyl-buffer gulp-uglify del gulp-rename --save-dev</code>

现在让我们开始在我们的 gulpfile.js 中使用这些包。我们需要编写一个任务来获取所有 ES6 文件并将它们传递给 Babel。Babel 中的默认模块系统是 CommonJS,因此我们不需要向 babel 函数发送任何选项。

<code>var babel = require('gulp-babel'),
    browserify = require('browserify'),
    source = require('vinyl-source-stream'),
    buffer = require('vinyl-buffer'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify'),
    del = require('del');

gulp.task('clean-temp', function(){
  return del(['dest']);
});

gulp.task('es6-commonjs',['clean-temp'], function(){
  return gulp.src(['app/*.js','app/**/*.js'])
    .pipe(babel())
    .pipe(gulp.dest('dest/temp'));
});
</code>

希望这里没有什么太令人困惑的地方。我们正在声明一个名为 es6-commonjs 的任务,它获取 app 目录及其任何子目录中的任何 JavaScript 文件。然后它将它们通过 Babel 传递,Babel 又将各个文件转换为 ES5 和 CommonJS 模块,并将转换后的文件复制到 dest/temp 文件夹中。es6-commonjs 任务有一个名为 clean-temp 的依赖项,它将在 es6-commonjs 任务运行之前删除 dest 目录及其中的任何文件。

如果您想使代码更明确并指定模块系统,您可以修改 Babel 的用法如下:

<code>.pipe(babel({
  modules:"common"
}))
</code>

现在,我们可以通过应用 Browserify 并使用 uglify 包压缩输出,从这些单个文件中创建一个单个捆绑文件。以下代码段显示了这一点:

<code>gulp.task('bundle-commonjs-clean', function(){
  return del(['es5/commonjs']);
});

gulp.task('commonjs-bundle',['bundle-commonjs-clean','es6-commonjs'], function(){
  return browserify(['dest/temp/bootstrap.js']).bundle()
    .pipe(source('app.js'))
    .pipe(buffer())
    .pipe(uglify())
    .pipe(rename('app.js'))
    .pipe(gulp.dest("es5/commonjs"));
});
</code>

上述任务有两个依赖项:第一个是 bundle-commonjs-clean 任务,它将删除 es5/commonjs 目录;第二个是前面讨论的 es6-commonjs 任务。这些任务运行后,该任务将组合和压缩后的文件 app.js 放入 es5/commonjs 文件夹中。此文件可以直接在 index.html 中引用,并且可以在浏览器中查看该页面。

最后,我们可以添加一个任务来启动操作:

<code>gulp.task('commonjs', ['commonjs-bundle']);
</code>

转换为 AMD

异步模块定义 (AMD) 系统,顾名思义,是一个异步模块加载系统。它允许并行加载多个依赖模块,并且它不会等待一个模块完全加载后再尝试加载其他模块。

Require.js 是用于处理 AMD 的库。RequireJS 可通过 Bower 获取:

<code>bower install requirejs --save</code>

我们还需要 Require.js 的 Gulp 插件来捆绑应用程序。为此,请安装 gulp-requirejs npm 包。

<code>npm install gulp-requirejs --save-dev</code>

现在,我们需要编写将 ES6 代码转换为 ES5 和 AMD 然后使用 RequireJS 捆绑它的任务。这些任务与 CommonJS 部分中创建的任务非常相似。

<code>var requirejs = require('gulp-requirejs');

gulp.task('es6-amd',['clean-temp'], function(){
    return gulp.src(['app/*.js','app/**/*.js'])
    .pipe(babel({ modules:"amd" }))
    .pipe(gulp.dest('dest/temp'));
});

gulp.task('bundle-amd-clean', function(){
  return del(['es5/amd']);
});

gulp.task('amd-bundle',['bundle-amd-clean','es6-amd'], function(){
  return requirejs({
    name: 'bootstrap',
    baseUrl: 'dest/temp',
    out: 'app.js'
  })
  .pipe(uglify())
  .pipe(gulp.dest("es5/amd"));
});

gulp.task('amd', ['amd-bundle']);
</code>

要在 index.html 页面上使用最终脚本,我们需要添加对 RequireJS、生成的脚本的引用,然后加载 bootstrap 模块。app 文件夹内的 bootstrap.js 文件引导 AngularJS 应用程序,因此我们需要加载它来启动 AngularJS 应用程序。

<code> src="bower_components/requirejs/require.js" >>
 src="es5/amd/app.js">>
>
  (function(){
    require(['bootstrap']);
  }());
>
</code>

结论

模块是 JavaScript 中长期以来一直缺乏的功能。它们将出现在 ES6 中,但不幸的是,它们当前的原生浏览器支持较差。但这并不意味着您今天无法使用它们。在本教程中,我演示了如何使用 Gulp、Babel 和各种插件将 ES6 模块转换为可在浏览器中运行的 CommonJS 和 AMD 格式。

至于 ES6?自发布以来,ES6 在社区中获得了广泛关注。它已被包括 Bootstrap 的 JavaScript 插件、Aurelia、Angular 2 和许多其他 JavaScript 库或框架使用。TypeScript 还添加了对包括模块在内的一些 ES6 功能的支持。学习并使用今天的 ES6 将减少将来转换代码所需的努力。

使用 Babel 和 Gulp 将 ES6 模块转译为 AMD 和 CommonJS 的常见问题解答 (FAQ)

使用 Babel 和 Gulp 将 ES6 模块转译为 AMD 和 CommonJS 的目的是什么?

使用 Babel 和 Gulp 将 ES6 模块转译为 AMD 和 CommonJS 是一个过程,允许开发人员使用最新版本的 JavaScript (ES6) 编写代码,然后将其转换为各种 JavaScript 引擎可以理解的版本。这特别有用,因为并非所有浏览器或环境都支持最新的 ES6 功能。通过转译代码,开发人员可以确保他们的应用程序可以在不同的平台上顺利运行。

Babel 如何帮助转译 ES6 模块?

Babel 是一个 JavaScript 编译器,主要用于将 ECMAScript 2015 (ES6 ) 代码转换为向后兼容的 JavaScript 版本,这些版本可以由较旧的 JavaScript 引擎运行。在转译 ES6 模块时,Babel 提供了像“babel-plugin-transform-modules-commonjs”这样的插件,这些插件将 ES6 模块语法转换为广泛支持的 CommonJS 语法。

Gulp 在转译过程中扮演什么角色?

Gulp 是一个任务运行器,可用于自动化转译过程。可以将其配置为监视 ES6 文件中的任何更改,并自动在其上运行 Babel 转译器。这使开发人员不必每次更改代码时都手动运行转译器。

我可以将 ES6 模块转译为 AMD 而不是 CommonJS 吗?

是的,您可以将 ES6 模块转译为异步模块定义 (AMD) 而不是 CommonJS。Babel 为此提供了名为“babel-plugin-transform-modules-amd”的插件。AMD 在处理 Web 浏览器环境中的大量模块时特别有用。

AMD 和 CommonJS 之间的区别是什么?

AMD 和 CommonJS 都是模块格式。它们之间的主要区别在于它们如何处理依赖项。AMD 支持异步加载依赖项,这可以提高浏览器环境中的性能。另一方面,CommonJS 同步加载依赖项,这更简单,并且在 Node.js 等服务器环境中运行良好。

如何指定要转译的 ES6 功能?

Babel 使用名为 .babelrc(或 babel.config.js)的配置文件,您可以在其中指定要转译的 ES6 功能。您可以在此文件中列出要使用的插件或预设。例如,要转译 ES6 模块,您将在配置中包含“babel-plugin-transform-modules-commonjs”或“babel-plugin-transform-modules-amd”。

使用 ES6 模块的好处是什么?

ES6 模块为 JavaScript 开发带来了许多好处。它们引入了一种用于从模块导入和导出函数、对象或值的标准语法,这可以使您的代码更井然有序且更易于管理。它们还支持静态分析,这可以提高性能并在编译时而不是运行时捕获错误。

如何调试转译后的代码?

调试转译后的代码可能具有挑战性,因为执行的代码与您编写的代码不同。但是,Babel 通过源映射的形式为这个问题提供了解决方案。源映射是一个文件,它将转译后的代码映射回原始源代码,允许您调试代码,就像它正在运行原始 ES6 代码一样。

我可以将 Babel 和 Gulp 与其他 JavaScript 框架一起使用吗?

是的,Babel 和 Gulp 不与任何特定的 JavaScript 框架绑定。它们可以与任何支持 ES6 的框架一起使用,包括 React、Angular、Vue.js 等。

是否有 Babel 和 Gulp 的替代方案用于转译 ES6 模块?

是的,Babel 和 Gulp 有几种替代方案可用于转译 ES6 模块。这些包括 TypeScript、Traceur 和 Rollup。这些工具各有优缺点,因此最佳选择取决于您的特定需求和偏好。

以上是使用Babel&Gulp将ES6模块转换为AMD和COMPORJS的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn