用Gulp、Babel等为浏览器构建ES6环境

ECMAScript 6 是 JavaScript 的最新版本,它带来了很多新特性——一些是社区乞求已久的,一些是颇具争议的。但不管你如何看待 ES6,都应该学习并使用它——因为就是这么酷。由于能在服务器端控制 JavaScript 版本,所以 ES6 在 node.js 或其它服务端框架运行良好,但在客户端中则不尽人意了。从一个复杂的 angular 或 ember 应用到一个简单的静态页面基本都含有几行 jQuery 代码。

但为何在浏览器中应用 ES6 会如此艰难呢?因为对于客户端的 JavaScript,它能否执行完全取决于浏览器对它的支持程度。而且这不是你所能控制的,也许你的浏览器支持 ES6,但更多浏览器的支持程度很低,甚至完全不支持。即使现代浏览器最终都支持 ES6,我们仍不得不对使用旧浏览器的用户负责。所以距离我们能安全地编写 ES6 代码,并让浏览器直接执行的日子,还有很长一段时间。

难道这就让我们向命运低头吗?难道注定要因为浏览器不得不接受旧版本的 JavaScript 吗?不,我们不必接受这种限制!我们还有别的选择——现在最佳的选择是编写 ES6 代码,并将其转译(transpile)或编译为 ES5 代码(兼容所有现代浏览器,如IE9+)。Babel 是主流的转译工具,它让转译过程变得简单,我们打算让这过程自动化,所以我们甚至可以不用考虑上述的限制!

长话短说

如果你只想要简洁的描述和本文所用到的纯代码,下面就是:

我们将会创建一个 gulpfile 去监听文件的更改,并用 Babel 将 ES6 代码自动转换到 CommonJS,然后用 Browserify 将 CommonJS 转为 合法的 ES5。当然,我们也会添加额外的插件,如 UglifyJS (为了最小化),source maps 和 livereload —— 因为这些工具都超级有用。

简单粗暴,下面是完整的 gulpfile 文件:

这没你想象中糟糕吧!我们在上面尝试了很多不同的东西。如果你有兴趣学习它们,我会鼓励你继续往下阅读,去了解它们是如何运行和为什么会这样运行的,这无疑会为浏览器构建出更可靠的 ES6 代码。

开始我们的 Gulpfile

我们将选择 gulp 作为自动化构建工具。gulp 是基于 JavaScript 编写的工具,它能运行特定任务,并监听文件是否被更改。当然,这取决于你在本地项目的目录下的 gulpfile.js 配置文件。除了 gulp,还有其它自动化构建工具(grunt 也是流行的构建工具),但由于 gulp 基于 node 的流(streams)实现,因此速度更快。

首先,我们初始化 package.json,并本地安装 gulp(如果你未曾安装,也可全局安装):

然后,创建一个空白的 gulpfile.js,并填充如下骨架:

上面没什么特别的地方。我们创建了空的 buildwatchdefault 任务。build 任务应包含所有构建 JavaScript 代码的逻辑。watch 任务监控 src/js 文件夹下的文件是否被更改(构建后的文件会放在 dist/js 下)。

执行以上这些任务:

到目前为止一切良好,对吧?下面就实际添加 ES6-to-ES5 构建处理。

执行 Babel 和 Browserify

在“长话短说”中我们简单讨论到,结合使用 babelbrowserify 将 ES6 代码转成浏览器能执行的 ES5 代码。Babel 能将 ES6 转为 CommonJS,而 CommonJS 是现今 JavaScript 最常用的模块模式(特别是在 node.js)。但现今浏览器仍不能识别 CommonJS。因此,我们需要使用 browserify 将 CommonJS 转为合法的 ES5。有了这两个工具,我们能走得更顺利。

然而我们不能直接使用 babel。取而代之的是 babelify 库,它是作为 browserify 的转换器——这意味着在 browserify 编译前,它会预处理 JavaScript。那我们先安装这些包(package):

现在,为了构建 ES6 代码,我们将 gulpfile 文件更改为:

这就是构建 JavaScript 代码的全部东西。我们简单地告诉 browserify,我们想改变的文件(此案例中,是 src/js/app.js),另外在代码被 browserify 处理(打包)前,使用预设值为 “es2015” 的 babel 对代码进行转译。自 babel v6.0.0 版本后,babel 需要指定预设值,然后根据预设值对 JavaScript 代码进行相应转译。 尽管这操作看起来有点麻烦,但这让开发者对整个处理过程有更多的控制权。由于我们想根据 es2015 的标准进行构建处理,我们需要通过 NPM 安装 babel-preset-es2015。

在文件被 browserify 处理后,将它们打包进一个单独文件(此案例中,也只有一个文件)。你可能想知道 vinyl-source-stream 是什么。gulp 是基于 node 流(stream)的,更具体地说,是基于 vinyl streams 的,这是一种虚拟的文件格式。Browserify 返回一个可读的 stream,但不是 vinyl stream。因此我们必须用 vinyl-source-stream 对 stream 进行相应转化,以确保 gulp 后续逻辑能继续执行。这是一个额外的插件,但它小巧且职责单一。

在 gulpfile 仅 20 行代码下,我们就能正式构建 ES6 代码为合法的 ES5 代码了。如果要编写生产环境的 JavaScript 代码,那么在这之前,还要 uglify(丑化压缩)、source maps 和 livereload。

添加 Uglify、Source Maps 和 LiveReload

将 ES6  代码转为合法的 ES5 代码只是一件事,但将其投入到生产环境则需确保代码是被压缩的和拥有 source map 文件。为了添加这些功能,我们要为 gulpfile 文件添加以下工具:

  • UglifyJS:丑化并压缩 JavaScript 文件。
  • Source Maps:这会有助于为压缩后的脚本进行调试。Source maps 将压缩后的文件代码映射到未压缩文件的具体位置。这对生产环境下的代码进行调试(debugging)变得更容易了。当然,source maps 文件只会在开发者工具的 console 窗口打开时才会下载,所以普通用户是不会下载它们的。
  • LiveReload:这工具在开发中特别有用。若其监听的文件发生变化时,它会自动刷新你的浏览器。还有个比较受欢迎的替代工具是 BrowserSync 。

先添加 UglifyJS。我们需要安装以下包(packages):

并修改 gulpfile 文件:

我们添加了 gulp-uglify 和 vinyl-buffer。gulp-uglify 是 gulp 的一个插件,它能压缩 JavaScript 代码。但 vinyl-buffer 有何用呢?由于 gulp-uglify 现在不支持 stream,而支持 buffer。vinyl-buffer 能将 stream 转为 buffer,让 gulp-uglify 能正常运行。

最后阶段了,让我们为 gulpfile 添加 source maps 和 livereload。同样地,先安装包(packages):

OK,下面是我们最后一次修改 gulpfile 文件了:

在压缩 JavaScript 代码前,要先初始化 source map。这就能让压缩后的代码映射到原来的代码上。然后,将 source map 作为单独一个文件保存在 maps/ 目录下。现在,每当你想查看压缩后的 JS 代码所对应的行数时,source map 就能告诉你其相应代码在未压缩文件的所在行数,这无疑让 debug 更轻松。

最后,让 livereoload 监听每个文件的变化,让每次构建迭代后都会刷新浏览器。为了以最简单的方式充分利用 livereload,可安装相应浏览器插件——我最喜欢的 Chrome 的插件

就这样吧!我们能正式用这 gulpfile 文件了。

结语

如果你遵循上述步骤(或只是复制了文章开头的 gulpfile 文件),那么你就拥有一个运行良好的、能将 ES6 代码转译成现代浏览器所识别的 ES5 代码的自动化构建系统(有一些不必要但很好的插件,如最小化和 source map)。我知道这里面有些知识点可能比较复杂,而如果你只是想为浏览器编写 ES5 代码,你大可不必深究它。但掌握它,能让你成为一个更好的开发人员。毕竟,你是在熟悉优雅的前端构建工具。

另外,我强烈建议你看看 ES6 文档,了解某些新特性能有效提高你的工作效率。就我个人而言,我对新的 class API 充满怨言(因为 JavaScript 是基于原型链继承的,而不是基于类。你可以看看我的相关 文章),但对模块模式系统(module pattern system)则喜爱有加,而且我打算经常使用它。如果你打算紧追语言的最新迭代版本,babel 和 gulp 能助你一臂之力。

打赏支持我翻译更多好文章,谢谢!

打赏译者

打赏支持我翻译更多好文章,谢谢!

任选一种支付方式

1 4 收藏 评论

关于作者:刘健超-J.c

前端,在路上...http://jchehe.github.io 个人主页 · 我的文章 · 19 ·     

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部