阅读更多
ES6作为新一代JavaScript标准,已正式与广大前端开发者见面。为了让大家对ES6的诸多新特性有更深入的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获授权,将持续对该系列进行翻译,组织成【探秘ES6】系列专栏,供大家学习借鉴。本文为该系列的第九篇。

本文接下来讲述的是有关Babel和Broccoli(花椰菜)的使用。

Babel的使用

Babel是一个源代码到源代码的转换器,例如ES6到ES5的转换并使代码在主流JS引擎中执行。

在项目中可通过多种方式来使用Babel,例如命令行方式,其格式为:
babel script.js --out-file script-compiled.js  

在浏览器中使用也是可以的,可以把Babel作为常规的JS库进行链接使用:
<script src="node_modules/babel-core/browser.js"></script>
<script type="text/babel">
// Your ES6 code
</script>

不过当你的基代码不断增加,则需要更具扩展性的方法以管道方式整合Babel。接下来会介绍如何使用创建工具Broccoli.js来对Babel进行整合。

第一个Broccoli及Babel项目

Broccoli是一个帮助快速创建项目的工具。透过Broccoli插件,可以压缩和管理文件,从而减轻我们的负担。当项目发生变动时,Broccoli可以帮助完成目录变更,执行命令等事情。

项目创建

NODE

如你所想,事前需要安装Node 0.11或更新版本。

如果使用的是unix系统,请不要使用包管理器(apt,yum)进行安装,这样做是为了避免Root权限的使用。我们建议以手动行方式完成,更具体原因点击这里进行查看,里面还介绍了其它的安装方式。

BROCCOLI

Broccoli项目创建第一步:
mkdir es6-fruits
cd es6-fruits
npm init
# Create an empty file called Brocfile.js
touch Brocfile.js

接着安装broccoli和broccoli-cli:
# the broccoli library
npm install --save-dev broccoli
# command line tool
npm install -g broccoli-cli

编写ES6代码

创建scr目录并存放fruits.js文件:
mkdir src
vim src/fruits.js

上述代码使用了3个ES6特性:
1.使用let进行本地声明;
2.使用for-of 循环
3.模板字符串

保存并执行:
node src/fruits.js  

使用Node或其它浏览器来执行:
let fruits = [
    ^^^^^^
SyntaxError: Unexpected identifier

转换时刻

现在我们使用Broccoli来载入代码然后透过Babel推送。编辑Brocfile.js添加以下代码:
// import the babel plugin
var babel = require('broccoli-babel-transpiler');

// grab the source and transpile it in 1 step
fruits = babel('src'); // src/*.js

module.exports = fruits;

注意这里要安装好Broccoli插件broccoli-babel-transpiler:
npm install --save-dev broccoli-babel-transpiler 

最后可以编译项目并执行:
broccoli build dist # compile
node dist/fruits.js # execute ES5

其输出结果应该是:
ID: 100 Name: strawberry
ID: 101 Name: grapefruit
ID: 102 Name: plum
List total: 3

是不是很简单?你可以打开dist/fruits.js来查看转换后的代码。Babel转换器的亮点是生成的代码具有良好的可读性。

为网站编写ES6代码

第二个例子会在第一个例子基础上进行修改。第一步,移出es6-fruits文件夹然后创建新的目录es6-website。

在src目录中创建三个文件:

src/index.html
<!DOCTYPE html>
<html>
  <head>
    <title>ES6 Today</title>
  </head>
  <style>
    body {
      border: 2px solid #9a9a9a;
      border-radius: 10px;
      padding: 6px;
      font-family: monospace;
      text-align: center;
    }
    .color {
      padding: 1rem;
      color: #fff;
    }
  </style>
  <body>
    <h1>ES6 Today</h1>
    <div id="info"></div>
    <hr>
    <div id="content"></div>

    <script src="//code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="js/my-app.js"></script>
  </body>
</html>

src/print-info.js
function printInfo() {
  $('#info')
  .append('<p>minimal website example with' +
          'Broccoli and Babel</p>');
}

$(printInfo);

src/print-colors.js
// ES6 Generator
function* hexRange(start, stop, step) {
  for (var i = start; i < stop; i += step) {
    yield i;
  }
}

function printColors() {
  var content$ = $('#content');

  // contrived example
  for ( var hex of hexRange(900, 999, 10) ) {
    var newDiv = $('<div>')
      .attr('class', 'color')
      .css({ 'background-color': `#${hex}` })
      .append(`hex code: #${hex}`);
    content$.append(newDiv);
  }
}

$(printColors);

你或许注意到一个细节:function* hexRange,没错,这就是ES6生成器,但该特性目前还不能兼容所有的浏览器。因此这里需要使用polyfill,其已包含在Babel中。

下一步是合并所有JS文件然后在网站上使用。最关键一步是要编写Brocfile文件。现在先安装4个插件:
npm install --save-dev broccoli-babel-transpiler
npm install --save-dev broccoli-funnel
npm install --save-dev broccoli-concat
npm install --save-dev broccoli-merge-trees

然后进行使用:
// Babel transpiler
var babel = require('broccoli-babel-transpiler');
// filter trees (subsets of files)
var funnel = require('broccoli-funnel');
// concatenate trees
var concat = require('broccoli-concat');
// merge trees
var mergeTrees = require('broccoli-merge-trees');

// Transpile the source files
var appJs = babel('src');

// Grab the polyfill file provided by the Babel library
var babelPath = require.resolve('broccoli-babel-transpiler');
babelPath = babelPath.replace(/\/index.js$/, '');
babelPath += '/node_modules/babel-core';
var browserPolyfill = funnel(babelPath, {
  files: ['browser-polyfill.js']
});

// Add the Babel polyfill to the tree of transpiled files
appJs = mergeTrees([browserPolyfill, appJs]);

// Concatenate all the JS files into a single file
appJs = concat(appJs, {
  // we specify a concatenation order
  inputFiles: ['browser-polyfill.js', '**/*.js'],
  outputFile: '/js/my-app.js'
});

// Grab the index file
var index = funnel('src', {files: ['index.html']});

// Grab all our trees and
// export them as a single and final tree
module.exports = mergeTrees([index, appJs]);

构建并执行代码:
broccoli build dist  

可以看到dist文件夹结构应该是这样的:



然后查看该静态网站:
cd dist/
python -m SimpleHTTPServer
# visit <a href="http://localhost:8000/">http://localhost:8000/</a>

其显示结果是:



Babel和Broccoli更多功能

如果你想使用Babel和Broccoli完成更多任务,不妨多看看这个项目:broccoli-babel-boilerplate。这也是一个Broccoli+Babel组合的项目,内容是涉及模块,导入和单元测试的处理。(译者:伍昆,责编:陈秋歌)

原文链接: ES6 In Depth: Using ES6 today with Babel and Broccoli

本译文遵循Creative Commons Attribution Share-Alike License v3.0
  • 大小: 1.4 KB
  • 大小: 25.9 KB
2
0
评论 共 2 条 请登录后发表评论
2 楼 yangsong158 2015-07-23 09:58
mangguo 写道
最近刚写了 ES6的课程

汇智的教程做得相当不错。
关键是还免费。
非常感谢无私奉献!
1 楼 mangguo 2015-07-22 17:11
最近刚写了 ES6的课程

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 智能指针与引用计数详解(一)

    前言 在C++项目开发中,有时候会遇到悬垂指针的问题,其中提供的解决方案推荐使用智能指针。 在《C++Primer》书13.5章 提到了该技术的具体使用场景和实现。通过反复阅读和代码测试终于了解其中的思想,下面谈谈自己的理解,如果发现有什么问题,请大家批评指正。 什么是智能指针? 智能指针其实就是一个类,除了增加了一些功能外,其因为跟跟普通指针一样。通常情况,new一个对象会申请一块内存,复制或者...

  • c语言指针的基本使用

    文章目录指针变量的定义和初始化指针操作按引用向函数传递参数const 修饰符sizeof 操作符指针表达式和指针运算指针数组函数指针 指针(pointer)是C语言中一个重点和难点,以下是对其基本使用的一些总结,适合入门的同学。除了是对自己的学习的总结之外,也希望能对大家有所帮助。 指针变量的定义和初始化 与C语言其他变量类似,指针也是一种变量,只不过它与其他变量不同,一般变量是直接包含了一个特定...

  • 513-带引用计数的智能指针

    带引用计数的智能指针:shared_ptr和weak_ptr 带引用计数的好处: 多个智能指针可以管理同一个资源。 C++11 boost库的智能指针拿到标准库里面 带引用计数:给每一个对象的资源,匹配一个引用计数 当1个智能指针引用这个资源的时候,这个资源相应的引用计数就加1,当这个智能指针出作用域,不再使用这个资源的时候,这个资源的引用计数就减1。 当引用计数减1不为0的时候,这个智能指针不使用这个资源了,但是还有其他智能指针在使用这个资源,这个智能指针不能析构这个资源,只能直接走人。 当引用计数减1为

  • C++ 引用计数技术及智能指针的简单实现

    文章也发布在 腾讯云+社区 一直以来都对智能指针一知半解,看C++Primer中也讲的不够清晰明白(大概是我功力不够吧)。最近花了点时间认真看了智能指针,特地来写这篇文章。 1.智能指针是什么 简单来说,智能指针是一个类,它对普通指针进行封装,使智能指针类对象具有普通指针类型一样的操作。具体而言,复制对象时,副本和原对象都指向同一存储区域,如果通过一个副本改变其所指的值,则通过另一对象访问的值也会...

  • 实现指针引用计数的类 Reference Counter

    使用一个指针指向一个动态对象,当不再使用的时候要销毁这个对象。如果会有多个指针指向同一个动态对象,那么需要知道,什么时候才能销毁这个对象。提前销毁对象可能导致指针指向并且销毁一个不存在的对象,不销毁则会是内存泄露。因此,有必要为指针设计一个引用计数机制,这个机制封装在一个类中。其实这就是一种智能指针。 http://blog.csdn.net/ojshilu/article/details/19

  • 智能指针的两种实现(引用计数)

    在微信上看到一篇“C++引用计数及智能指针的简单实现”的好文章点击打开链接,通俗易懂,激起了敲代码的兴趣,于是用两种方式实现了简单的智能指针(辅助类+SmartPtr类 vs SmartPtr类)。关于什么是智能指针以及普通指针所存在的问题,查看该文即可(讲的很好)点击打开链接,本文仅列出两种实现方式的代码,希望对大家有所帮助,若存在问题,欢迎指针,谢谢! 方式一:辅助类+Smart

  • 一个简单的引用计数实现体类

     本文主要介绍一个简单的引用计数实现体类,它被引用计数对象(请参考:http://blog.csdn.net/hello_wyq/archive/2006/07/07/888606.aspx)所使用。它私用继承了Noncopyable对象(请参考:http://blog.csdn.net/hello_wyq/archive/2006/07/07/888550.aspx),以便禁止对象的拷贝和赋值操

  • 引用计数的智能指针的实现与思考

    引用计数的智能指针的实现与思考 引用计数在软件开发中是一项非常重用的技术,它可以说是无处不,我们在不知不觉中都在和它打交道,比如 Windows上的COM和Handle, Mac上的ref句柄,脚本语言中的垃圾回收技术。 但是在C++标准库中,却没有内置支持引用计数的技术的支持,下面我们就尝试封装自己的基于引用计数的智能指针。 一般来说,计数方法的实现有2种,内置和外置: 内置指的是对象本身就有计数功能,也就是计数的值变量是对象的成员;外置则是指对象本身不需要支持计数功能,我们是在外部给它加上这个计数能力

  • 一个简单引用计数智能指针的实现

    template &amp;lt;typename T&amp;gt; class SharedPtr{ public: SharedPtr() = delete;//不允许未初始化的智能指针,防止使用空指针 SharedPtr(const SharedPtr&amp;amp;) noexcept; //拷贝构造 SharedPtr(T*) noexcept; //shallow copy ...

  • 记录c++知识--------实现一个行为像指针的类(引用计数)

    class hasptr { private: string *ps; int i; int *use; public: //这种默认构造函数挺好的,即使没给值,也会自动给一个默认空值 hasptr(const string &amp;s = string()) :ps(new string(s)), i(0), use(new int(0)) {}; //拷贝构造函数 hasp...

  • C++智能指针之shared_ptr

    shared_ptr是一个引用计数智能指针,用于共享对象的所有权。它可以从一个裸指针、另一个shared_ptr、一个auto_ptr、或者一个weak_ptr构造。 1、shared_ptr的构造函数 (1) 这个构造函数获得给定指针p的所有权。参数p必须是指向T的有效指针。构造后引用计数设为1。 template &amp;lt;class T&amp;gt; explicit shared_ptr(T* ...

  • 实现一个带引用计数的shared_ptr智能指针

    *自定义一个myShared_ptr结构,包含引用计数、运算符、-&gt;运算符 // 自定义 shared_ptr 智能指针 template&lt;class T&gt; class myShared_ptr { public: // 构造函数 myShared_ptr(T* ptr) : _ptr(ptr), _pCount(new int(1)) {} // 拷贝构造函数 myShared_ptr(const myShared_ptr&amp; sp) : _ptr(sp._ptr)

  • 自己实现一个带引用计数的智能指针,根据源码

    //存储资源引用计数的表,使用单例模式因为模板在类型推导的时候 //会因为类型的不同从而产生不同的表,对于引用计数来说会产生错误 //因为这两张表应该在同一张表中,在调试中遇到的这个问题 class ResTable { public: typedef map::iterator iterator; /* 快加载:没调用getInstance函数,对象实例就生成了 慢加载:第一次调用ge

  • 通过引用计数实现智能指针

    通过模板和引用计数的方式实现智能指针,需要两个类:智能指针类SmartPtr,和智能指针辅助类SmartPtrHelper,其中用户接触到是SmartPtr类,而SmartPtr类通过SmartPtrHelper管理指针的内存和计数。具体实现如下: SmartPtrHelper类 //模板类作为友元时要先有声明 template &amp;lt;typename T&amp;gt; class SmartP...

  • java引用计数

    http://zhangjunhd.blog.51cto.com/113473/53092/ http://thatmonkey.blog.51cto.com/7935609/1384463

  • 【C++】智能指针之引用计数的实现

    本文将简单的介绍,C++11中的智能指针的引用计数大致是如何实现的。部分内容节选自 C++ primer 5th。

  • 引用计数的智能指针——sharedptr的模拟实现

    在处理异常时,由于要抛出异常,经常导致申请空间未释放,打开的文件未关闭等情况,这时,智能指针便应运而生。       智能指针功能和普通指针最大的区别就在于智能指针在退出堆栈时会自动调用析构函数而不会存在忘记释放空间的问题,而且它任然可以对指针进行赋值、解引用等操作。那就来简单的实现一下智能指针吧。 template class SharedPtr { public: SharedP

  • C++ 引用计数

    C++没有像java那样的垃圾回收机制,但是我们可以实现一个。一种很简单的方式就是使用引用计数。它实际上是一种用对象来管理资源的方式,因为普通的栈上的对象在离开作用域时会调用对应的析构函数,根据这个特性,可以实现用于对指针进行管理的类。 下面以一个对int*指针的管理来说明引用计数是如何实现的。 当我们创建一个int型指针时:int *p=new int(10); 在最后我们需要调用dele

  • Java引用计数与实现

    引用计数(Reference Counting)可作为内存管理办法,也是老代jvm垃圾回收策略之一,原理简单但是仍有广泛的引用,如OkHttp,netty等。 回收原理 对象在创建实例的时候会在堆内存申请内存时给对象引用记为1,当有其他对象新增对此对象的引用持有时,就把改对象的引用计数+1,释放引用时-1,直至引用计数减至0,该对象的内存就会被释放。 特征 优点: 回收及时:引用数为0,立即回收...

Global site tag (gtag.js) - Google Analytics