当前位置: 首页 > 工具软件 > gulp-tutorial > 使用案例 >

babel gulp_使用Babel和Gulp将ES6模块移植到AMD和CommonJS

夹谷苗宣
2023-12-01

babel gulp

ECMAScript 6 (a.k.a ECMAScript 2015 or ES6), the specification for next version of JavaScript has been approved and browser vendors are hard at work implementing it. Unlike the previous versions of ECMAScript, ES6 comes with a huge set of changes to the language to make it a good fit for the scale at which it is used today. Sitepoint has a number of articles covering these features.

ECMAScript 6(又名ECMAScript 2015或ES6),下一版本JavaScript的规范已获得批准 ,浏览器供应商正在努力实现它。 与早期版本的ECMAScript不同,ES6对该语言进行了大量更改,使其非常适合当今使用的规模。 Sitepoint有许多有关这些功能的文章

Although browsers haven’t implemented all of the features yet, we can already take advantage of ES6 during development and convert it to a version that browser understands before shipping the application. Babel and Traceur are two of the leading transpilers used for this purpose. Microsoft’s typed superset of JavaScript, TypeScript can also be used as an ES6 transpiler.

尽管浏览器尚未实现所有功能,但是我们已经可以在开发过程中利用ES6,并将其转换为浏览器可以理解的版本,然后再交付应用程序。 BabelTraceur是用于此目的的两个领先的编译器。 Microsoft的类型化JavaScript超集TypeScript也可用作ES6编译器。

I covered how ES6 can be used today to write Angular 1.x applications in one of my previous articles. In that article I used Traceur’s on-the-fly transpiler to run the application. Although it works, it is always better to transpile beforehand and reduce the amount of work to be done in the browser. In this article, we will see how the same sample application can be transpiled to ES5 and the modules into either CommonJS or, AMD using Babel to make it run on today’s browsers. Though the sample is based on Angular, the techniques of transpilation can be used with any valid ES6 code.

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

As ever, you can find the code to accompany this article on our GitHub repo.

与往常一样,您可以在我们的GitHub repo上找到本文随附的代码。

模块的重要性 (The Importance of Modules)

One of the key features in any language used to write large applications, is the ability to load different pieces of the application in the form of modules. Modules not only help us keep the code cleaner but they also play a role in reducing the usage of global scope. The contents of a module are not made available to any other module unless the other module explicitly loads it.

任何用于编写大型应用程序的语言的主要功能之一就是能够以模块的形式加载应用程序的不同部分。 模块不仅帮助我们保持代码更整洁,而且在减少全局范围的使用方面也发挥了作用。 除非另一个模块显式加载该模块的内容,否则该模块的内容不可用于任何其他模块。

The importance of modules is not limited to applications. Even large JavaScript libraries can take advantage of the module system to export their objects as modules and the applications using the libraries import these modules as required. Angular 2 and Aurelia have started using this feature.

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

If you’d like a quick primer on using modules in ES6, please read: Understanding ES6 Modules

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

关于示例应用程序 (About the Sample Application)

The subject of our sample application is a virtual book shelf. It consists of the following pages:

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

  1. Home page: shows a list of active books that can be marked as read, or moved to the archive.

    主页:显示可标记为已读或移至档案的活动书的列表。
  2. Add book page: adds a new book to the shelf by accepting title of the book and name of author. It doesn’t allow a duplicate titles.

    添加书页:通过接受书名和作者姓名将新书添加到书架中。 它不允许重复的标题。
  3. Archive page: lists all archived books.

    存档页面:列出所有已存档的书籍。

The application is built using AngularJS 1.3 and ES6. If you look at any of the files in the app folder, you will see the keywords export and import used to export objects from the current module and to import objects from other modules. Now, our job is to use Babel’s Gulp tasks to convert these modules to one of the existing module systems.

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

但是我没有使用Angular。 我只想将ES6模块转换为CommonJS / AMD (But I’m Not Using Angular. I Just Want to Convert ES6 Modules to CommonJS/AMD)

No worries! We got you covered. With a minor amount of tweaking the recipes demonstrated below can be used in any project involving ES6 modules. Angular is quite unimportant here.

别担心! 我们得到了你的覆盖。 只需进行少量调整,以下演示的配方就可以用于任何涉及ES6模块的项目。 Angular在这里并不重要。

转换为CommonJS (Converting to CommonJS)

CommonJS is a module system defined by the CommonJS group. It is a synchronous module system, in which the modules are loaded using the require function and exported using the exports property of the module object. The module object is expected to be available in all modules by default.

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

Node.js uses this module system, so it defines the module object natively and makes it available to your application. As browsers don’t have this object defined, we need to use a utility called Browserify to fill the gap.

Node.js使用此模块系统,因此它本地定义了module对象,并使它可用于您的应用程序。 由于浏览器未定义此对象,因此我们需要使用名为Browserify的实用程序来填补空白。

Before we start, we will also need to install a few npm packages. These will enable us to use Babel and Browserify in conjunction with Gulp to convert our ES6 modules to one of the common module formats and package the application as a single file for the browser to consume.

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

  • gulp-babel — converts ES6 code into vanilla ES5

    gulp-babel —将ES6代码转换为原始ES5

  • Browserify — lets you require('modules') in the browser by bundling up all of your dependencies

    Browserify-通过捆绑所有依赖 ,使您在浏览器中require('modules')

  • vinyl-source-stream — handles the Browserify module directly, avoiding need for gulp-browserify wrapper

    Vinyl-Source-Stream —直接处理Browserify模块,避免使用gulp - browserify包装器

  • vinyl-buffer — converts stream to a buffer (necessary for gulp-uglify which doesn’t support streams)

    Vinyl-Buffer —将流转换为缓冲区(对于不支持流的gulp-uglify是必需的)

  • gulp-uglify — minifies files

    gulp - uglify-缩小文件

  • del — lets you delete files and folders

    del-可让您删除文件和文件夹

  • gulp-rename — a plugin to let you rename files

    gulp-rename-一个让您重命名文件的插件

You can get this lot by typing:

您可以通过输入以下内容来获得很多:

npm install gulp-babel browserify gulp-browserify vinyl-source-stream vinyl-buffer gulp-uglify del gulp-rename --save-dev

Now let’s start using these packages in our gulpfile.js. We need to write a task to take all ES6 files and pass them to Babel. The default module system in Babel is CommonJS, so we don’t need to send any options to the babel function.

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

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'));
});

Hopefully there is nothing too confusing here. We are declaring a task named es6-commonjs which grabs any JavaScript files in the app directory and any of its sub directories. It then pipes them through Babel, which in turn converts the individual files to ES5 and CommonJS modules and copies the converted files into the dest/temp folder. The es6-commonjs task has a dependency named clean-temp, which will remove the dest directory and any files in it, before the es6-commonjs task runs.

希望这里没有太混乱的地方。 我们正在声明一个名为es6-commonjs的任务,该任务将抓取app目录及其子目录中的所有JavaScript文件。 然后,它将它们通过Babel进行管道传输,Babel随后将各个文件转换为ES5和CommonJS模块,并将转换后的文件复制到dest/temp文件夹中。 es6-commonjs任务具有一个名为clean-temp的依赖项,它将在es6-commonjs任务运行之前删除dest目录及其中的任何文件。

If you want to make the code more explicit and specify the module system, you may modify usage of Babel as:

如果要使代码更明确并指定模块系统,则可以将Babel的用法修改为:

.pipe(babel({
  modules:"common"
}))

Now we can create a single bundled file from these individual files by applying Browserify and then minifying the output using the uglify package. The following snippet shows this:

现在,我们可以通过应用Browserify,然后使用uglify软件包最小化输出,从这些单独的文件中创建一个捆绑文件。 以下代码片段显示了这一点:

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"));
});

The above task has two dependencies: the first is the bundle-commonjs-clean task, which will delete the directory es5/commonjs, the second is the previously discussed es6-commonjs task. Once these have run, the task places the combined and minified file app.js in the folder es5/commonjs. This file can be referenced directly in index.html and the page can be viewed in a browser.

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

Finally, we can add a task to kick things off:

最后,我们可以添加一个任务来开始工作:

gulp.task('commonjs', ['commonjs-bundle']);

转换为AMD (Converting to AMD)

The Asynchronous Module Definition (AMD) system is, as the name suggests, an asynchronous module loading system. It allows multiple dependent modules to load in parallel and it doesn’t wait for one module to be completely loaded before attempting to load other modules.

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

Require.js is the library used to work with AMD. RequireJS is available through Bower:

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

bower install requirejs --save

We also need the Gulp plugin for require.js to bundle the application. Install the gulp-requirejs npm package for this.

我们还需要Gulp插件用于require.js来捆绑应用程序。 为此安装gulp-requirejs npm软件包。

npm install gulp-requirejs --save-dev

Now we need to write the tasks for converting the ES6 code to ES5 and AMD and then to bundle it using RequireJS. The tasks are pretty much similar to the tasks created in the CommonJS section.

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

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']);

To use the final script on index.html page, we need to add a reference to RequireJS, the generated script and then load the bootstrap module. The bootstrap.js file inside app folder bootstraps the AngularJS application, so we need to load it to kick start the AngularJS application.

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

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

结论 (Conclusion)

Modules are a long overdue feature in JavaScript. They will be arriving in ES6, but unfortunately, their native browser support is currently poor. That does not however, mean that you cannot use them today. In this tutorial I have demonstrated how to use Gulp, Babel and a variety of plugins to convert ES6 modules to the CommonJS and AMD format that you can run in your browser.

模块是JavaScript中早就应该使用的功能。 他们将在ES6中推出,但是不幸的是,它们对本机浏览器的支持目前很差。 但是,这并不意味着您今天不能使用它们。 在本教程中,我演示了如何使用Gulp,Babel和各种插件将ES6模块转换为可在浏览器中运行的CommonJS和AMD格式。

And as for ES6? ES6 has gained a lot of attention in the community since it was announced. It is already used by several JavaScript libraries or, frameworks including Bootstrap’s JavaScript plugins, Aurelia, Angular 2 and several others. TypeScript has also added support for a handful number of ES6 features including modules. Learning about and using ES6 today, will reduce the effort required to convert the code in future.

至于ES6? 自发布以来,ES6在社区引起了很多关注。 它已经被多个JavaScript库或框架(包括BootstrapJavaScript插件,Aurelia,Angular 2以及其他一些框架)使用。 TypeScript还增加了对包括模块在内的少数ES6功能的支持。 今天学习和使用ES6将减少将来转换代码所需的工作。

翻译自: https://www.sitepoint.com/transpiling-es6-modules-to-amd-commonjs-using-babel-gulp/

babel gulp

 类似资料: