ecmascript和babel的渊源

ecma

  • 中文名: 欧洲计算机制造联合会
  • 外文名: European Computer Manufactures Association
  • 地 区: 日内瓦
  • 缩 写: ECMA
  • 目 的: 信息处理和电信系统
  • 包 括: 程序语言和输入输出
  • 组 织: 国际标准化组织
这个组织的目标是评估,开发和承认电信和计算机标准。你们决定把ECMA的总部设在日内瓦是由于这样可以让它与其它与之协同工做的标准制定组织更接近一些,比方说国际标准化组织(ISO)和国际电子技术协会(IEC)。ECMA是“European Computer Manufactures Association”的缩写,中文称欧洲计算机制造联合会。是1961年成立的旨在创建统一的电脑操做格式标准--包括程序语言和输入输出的组织。
主要任务是研究信息和通信技术方面的标准并发布有关技术报告。ECMA并非官方机构,而是由主流厂商组成的,他们常常与其余国际组织进行合做。就象ECMA的章程中所说的那样,这个非盈利组织的目标是发展“标准和技术报告以便促进和标准化对信息处理和电信系统的使用过程。

目前已经能够确认的标准:注:此名单仅部分收录javascript

ECMA-6 7位被编码的字符集(同同样 ISO/IEC 646/ITU-T T.50)
ECMA-13文件结构和标记磁带(最新ISO 1001)
ECMA-35 ISO/IEC 2022年 字符内码
ECMA-43 8位被编码的字符集(和同样ISO/IEC 4873)
ECMA-48 ANSI逃命代码 (和同样ISO/IEC 6429)
ECMA-58 8英寸 软盘
ECMA-59 8英寸 软盘
ECMA-66 5¼-英寸 软盘
ECMA-69 8英寸 软盘
ECMA-70 5¼ -英寸 软盘
ECMA-74信息技术和电信设备散发的空气传播的噪音的测量(和同样ISO 7779)
ECMA-78 5¼ -英寸 软盘
ECMA-94 8位编码字符集(同同样 ISO/IEC 8859-1, -2, -3和-4)
ECMA-99 5¼-英寸1.2兆字节 软盘 (也ISO 8630)
ECMA-100 3½-英寸 软盘 (也ISO 8660)
ECMA-107 文件分配表 (FAT)文件系统
ECMA-113 8位被编码的字符集,拉丁语或斯拉夫(同同样 ISO/IEC 8859-5)
ECMA-114 8位被编码的字符集,拉丁语或阿拉伯语(同同样 ISO/IEC 8859-6)
ECMA-118 8位被编码的字符集,拉丁语或希腊语(同同样 ISO/IEC 8859-7)
ECMA-119 CD-ROM 文件系统(之后被采起 ISO 9660:1988)
ECMA-121 8位被编码的字符集,拉丁语或希伯来语(同同样 ISO/IEC 8859-8)
ECMA-125 3½-英寸 软盘 (也ISO 9529)
ECMA-128 8位被编码的字符集(同同样 ISO/IEC 8859-9)
ECMA-130 CD-ROM 黄皮书
ECMA-139 4mm 数字资料存贮 (二氨基二苯基砜)弹药筒(和同样ISO/IEC 10777)
ECMA-144 8位被编码的字符集(同同样 ISO/IEC 8859-10)
ECMA-146 4mm DAT 数据插件(和同样ISO/IEC 11321)
ECMA-167 广泛盘格式
ECMA-168 ISO 9660 第3级(ISO/IEC 13490)
ECMA-182 周期性多余信息检验 多项CRC-64-ECMA-182
ECMA-234应用程序编程接口为 窗口3.1
ECMA-262 ECMAScript (规范化 脚本(script)语言)
ECMA-334 C#编程语言
ECMA-335 共同语言基础设施
ECMA-340 NFC标准ISO18092(ECMA免费版)
ECMA-352 NFC标准ISO21481(ECMA免费版)
ECMA-357 ECMAScript为XML (E4X)
ECMA-363 通用3D 文件格式
ECMA-365 通用媒体光盘(用于PSP)
ECMA-368 超宽物理和MAC层
ECMA-369 超宽MAC-PHY接口
ECMA-372 C++/CLI
ECMA-376 办公文档开放XML
ECMA-377 200GB的HVD插卡
ECMA-378 100GB的HVD-ROM光碟

而其中就有本文重点介绍的ECMAscripthtml

ECMAscript/ES5/ES6/ES20XX

这里主要简单的介绍一下关于JavaScript的一些历史。前端

ECMAscript

ECMAscript是基于Netscape javaScript的一种标准脚本语言。它也是一种基于对象的语言,经过DOM能够操做网页上的任何对象。能够增长、删除、移动或者改变对象。使得网页的交互性大大提升。更多ECMAscript信息和历史java

ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会)经过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用普遍,它每每被称为 JavaScriptJScript,但实际上后二者是 ECMA-262标准的实现和扩展。

ECMA的第39号技术专家委员会(Technical Committee 39,简称TC39)负责制订ECMAScript标准,成员包括Microsoft、Mozilla、Google等大公司。TC39的整体考虑是,ES5与ES3基本保持兼容,较大的语法修正和新功能加入,将由JavaScript.next完成。node

了解更多TC39的进度能够关注tc39ecma262--githubtc39标准进度webpack

ECMAscript/ES历史

ESECMAScript 的缩写。每次看到 ES 后面跟着数字,是 ECMAScript 的不一样版本。实际上一共有 9 个版本【截止时间2018年,2018-11月的部分达到stage4的提案已经做为ES2019的部分了】。咱们来深刻了解下:git

  1. ES1:1997 年 6 月  ——  
  2. ES2:1998 年 6 月  ——  
  3. ES3:1999 年 12月  ——  
  4. ES4:未经过

这是前 4 个版本的 ECMAScript,这里简单过一下。仅仅让你知道前 3 个版本每一年出一个,而第 4 个版本由于政治因素未经过。es6

  • ES5:2009 年 12月:将近 10 年以后,ES5 在 2009 年发布。而下个版本的 ECMAScript 也花了 6 年才发布,【目前ie8还有部分标准没有实现】。
  • ES6/ES2015:2015 年 6 月:也许困惑就是从这里开始的。你能够看到, ES6 和 ES2015 其实是同一个东西。
    起先被推广的名字是 ES6 。然而组委会要求 ECMAScript 必须作到每一年作一次更新。由此,这个版本被改名为 ES 2015,且每一年都须要更新,并命名为当前年的后缀。github

    从 2009 年发布的 ES5 到 2015 年发布的 ES6 共经历了 6 年,语言的变化很是大,引入了不少新的语法和特性。为了不剧烈的变更,从 ES7(2016) 开始,版本发布会变得更加频繁,每次的变更也更小。每一年会发布一个新版本,其中包含全部已经完成的特性。
  • ES2016(ES7):2016 年 6 月:ECMAScript 的第 7 个版本。
  • ES2017(ES8):2017 年 6 月:ECMAScript 的第 8 个版本。
  • ES2018(ES9):2018 年 6 月:ECMAScript 的第 9 个版本。

由此能够知道,日后应scma组委会要求,TC39每一年都会提交一个版本,可能每一年提交的版本修改并不会增长很是多,但仍是须要时刻关注web

stage【新增特性过程】

每一项新特性,要最终归入 ECMAScript 规范中,TC39 拟定了一个处理过程,称为 TC39 process。其中共包含 5 个阶段,Stage 0 ~ Stage 4stage的每一个特性所处阶段记录--stage英文文档介绍

TC39 遵循的原则是:分阶段加入不一样的语言特性。一旦提案成熟,TC39 会根据提案中的变更来更新规范。直到最近,TC39 依然依赖基于 Microsoft Word 的比较传统的工做流程。但 ES3 出来以后,为了使其达到规范,总共花了十年时间,几乎没有任何改变。以后,ES6 又花了四年才能实现。

ES6 出来以后,他们精简了提案的修订过程,以知足现代化开发的需求。新流程使用 HTML 的超集来格式化提案。他们使用 GitHub pull requests,这有助于增长社区的参与,而且提出的提案数量也增长了。这个规范如今是一个 living standard,这意味着提案会更快,并且咱们也不用等待新版本的规范出来。

新流程涉及五个不一样的 Stage。一个提案越成熟,越有可能最终将其归入规范。

  1. Stage 0: strawman
    任何还没有提交做为正式提案的讨论、想法变动或者补充都被认为是第 0 阶段的“稻草人(strawman)”提案。

    任何 TC39 成员,或者注册为 TC39 贡献者的会员,均可以提交 Stage 0 的提案。
  2. Stage 1: proposal
    该阶段产生一个正式的提案。肯定一个带头人来负责该提案,带头人(或者联合带头人)必须是 TC39 的成员。描述清楚要解决的问题,

    解决方案中必须包含例子, API(high level AP) 以及关于相关的语义和算法。潜在问题也应该指出来,例如与其余特性的关系,实现它所面临的挑战。polyfill 和 demo 也是必要的。
  3. Stage 2: draft
    Stage 2 的提案应提供规范初稿。此时,语言的实现者开始观察 runtime 的具体实现是否合理。该实现可使用 polyfill 的方式,以便使代码可在 runtime 中的行为负责规范的定义。javascript 引擎的实现为提案提供了原生支持。或者能够 Babel 这样的编译时编译器来支持。本草案与最终标准中包含的特性不会有太大差异。草案以后,原则上只接受增量修改。

    草案中包含新增特性语法和语义的,尽量的完善的形式说明,容许包含一些待办事项或者占位符。必须包含 2 个实验性的具体实现,其中一个能够是用转译器实现的,例如 Babel。
  4. Stage 3: candidate
    Stage 3 提案是建议的候选提案。在这个高级阶段,规范的编辑人员和评审人员必须在最终规范上签字。Stage 3 的提案不会有太大的改变,在对外发布以前只是修正一些问题。规范文档必须是完整的,评审人和 ECMAScript 的编辑要在规范上签字。至少要有 2 个符合规范的具体实现。
  5. Stage 4: finished
    最后,当规范的实现至少经过两个验收测试时,提案进入 Stage 4。进入 Stage 4 的提案将包含在 ECMAScript 的下一个修订版中。

    经过 Test 262 的验收测试。有 2 个经过测试的实现,以获取使用过程当中的重要实践经验。ECMAScript 的编辑必须规范上的签字。规格修订和调度

TC39 打算每一年七月向 ECMA 大会提交一份规范批准。如下是生成新规格修订的大体时间表:

  • 2月1日:候选草案被生成。
  • 2月-3月:60 天时间进行投票决定草案的去留。
  • 3月 TC39 会议:第 4 阶段的提案被归入,最终的语义被批准,从 master 新建一个 spec 的分支版本。只有编辑性的改变才能被接受。
  • 4月-6月:ECMA CC 和 ECMA GA 审查期。
  • 7月:由 ECMA 大会批准新标准

能够知道,每年度的版本其实在当年的7-8月份已经基本肯定,而后开始下一年的进度。

也正是因为历史缘由,有4点须要注意【如下截止时间2018-12,内容会被不断地调整】:

  1. ES5的修改经历了10年,而其中不少都是咱们前端常常用到的内容,ES5的修改内容能够参考:Standard ECMA-262, 5.1 Edition / June 2011,因为标准都是向前兼容的,因此这个版本包含了es3以前的标准,es5增长的标准列表;
  2. ES6也是经历了6年时间,在2015年发布的,其中又发生了不少的变化,查看ES6的标准:es6标准,通用也是包含了es5和以前的标准,es6增长的标准列表1--es6增长的标准列表1
  3. 为了不这种较大的改动,TC39将会在每一年提交一个版本,这样的变化在2016年开始,而从2016~2018年中的已经完成到stage4的提案列表:es2016+的已定标准变化
  4. 而每年的天的各个阶段会有变化,查看当前年份的有效天内容:当前年份的活跃天stage3~1

标准的发布,各大厂商是须要时间去作实现的,因此若是开发人员想第一时间来体验新的提案带来的便捷,确定是须要把提案中的内容经过相似polyfill的方式来使用,这就是本文另外一个重点babel的做用。

babel的出现

Babel 是一个通用的多用途 JavaScript 编译器。经过 Babel 你可使用(并建立)下一代的 JavaScript,以及下一代的 JavaScript 工具。

babel简介

做为一种语言,JavaScript 在不断发展,新的标准/提案和新的特性层出不穷。 在获得普遍普及以前,Babel 可以让你提早(甚至数年)使用它们。

Babel 把用最新标准编写的 JavaScript 代码向下编译成能够在今天随处可用的版本。 这一过程叫作“源码到源码”编译, 也被称为转换编译(transpiling,是一个自造合成词,即转换+编译。如下也简称为转译)。

例如,Babel 可以将新的 ES2015 箭头函数语法:

const square = n => n * n;
// 转译为:
const square = function square(n) {
  return n * n;
};

不过 Babel 的用途并不止于此,它支持语法扩展,能支持像 React 所用的 JSX 语法,同时还支持用于静态类型检查的流式语法(Flow Syntax)

更重要的是,Babel 的一切都是简单的插件,谁均可以建立本身的插件,利用 Babel 的所有威力去作任何事情。

再进一步,Babel 自身被分解成了数个核心模块,任何人均可以利用它们来建立下一代的 JavaScript 工具。

babel7使用

因为 JavaScript 社区没有统一的构建工具、框架、平台等等,所以 Babel 正式集成了对全部主流工具的支持。 从 Gulp 到 Browserify,从 Ember 到 Meteor,无论你的环境设置如何,Babel 都有正式的集成支持。

鉴于babel的灵活性,除了配置主流工具webpackgulp等使用,也能够独自使用;

  1. CLI: 使用命令来进行编译
  2. Require hook: 在须要编译的文件中引入require("babel-register");/import "babel-register";来编译当前文件。

不过两者都须要配合配置文件.babelrc使用;下面主要示范CLI的使用。

Babel/CLI

BABELCLI 是一种在命令行下使用 Babel 编译文件的简单方法。

让咱们先全局安装它来学习基础知识。

$ npm install -D babel-cli

咱们能够这样来编译咱们的第一个文件:

$ ./node_modules/.bin/babel my-file.js

这将把编译后的结果直接输出至终端。使用 --out-file 或着 -o 能够将结果写入到指定的文件。.

$ ./node_modules/.bin/babel example.js --out-file compiled.js
# 或
$ ./node_modules/.bin/babel example.js -o compiled.js

若是咱们想要把一个目录整个编译成一个新的目录,可使用 --out-dir 或者 -d。.

$ ./node_modules/.bin/babel src --out-dir lib
# 或
$ ./node_modules/.bin/babel src -d lib

通常而言,编译会被放在package.jsonscripts字段当中,

"scripts": {
    "test": "./node_modules/mocha/bin/mocha",
    "build": "./node_modules/.bin/babel src -d lib",
    "prepublish": "npm run build"
  },

配置文件.babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": [
            "last 2 versions",
            "safari >= 7"
          ],
          "chrome": 52,
          "node": "6.10.0"
        },
        "modules": "commonjs",
        "useBuiltIns": "usage"
      }
    ]
  ],
  "plugins": [
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-syntax-import-meta",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-nullish-coalescing-operator",
    "@babel/plugin-proposal-do-expressions"
  ]
}

plugins

pluginsbabel实现es2015+的新的语法,而每实现一种语法的编译,都是一个plugins

实例:@babel/plugin-transform-arrow-functions能够实现下面这个编译过程。

const square = n => n * n;
// 转译为:
const square = function square(n) {
  return n * n;
};

目前的plugins的集合目前能够查看:babel的plugins集合

@babel/preset-env

Sidenote, if no targets are specified, @babel/preset-env behaves exactly the same as @babel/preset-es2015, @babel/preset-es2016 and @babel/preset-es2017 together (or the deprecated babel-preset-latest).

能够知道,@babel/preset-env是完成了stage4之内的全部语法,同时添加了更多的配置项;

"presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": [
            "last 2 versions",
            "safari >= 7"
          ],
          "chrome": 52,
          "node": "6.10.0"
        },
        "modules": "commonjs",
        "useBuiltIns": "usage"
      }
    ]
  ],

更多的详细信息查看:babel的预设使用

比较重要的是三个地方:

  1. targets字段:适配所包含的运行环境,根据环境进行打包。
  2. modules打包后的模块:
  3. useBuiltInspolyfill的引入方式,
    "usage" | "entry" | false, defaults to false.

polyfill

Babel 是处于构建时(也就是传统Java等语言的编译时),转译出来的结果在默认状况下并不包括 ES6 对运行时的扩展,例如,builtins(内建,包括 Promise、Set、Map 等)、内建类型上的原型扩展(如 ES6 对 Array、Object、String 等内建类型原型上的扩展)以及Regenerator(用于generators / yield)等都不包括在内。

须要配合useBuiltIns字段来使用。

  1. "useBuiltIns": false
    不在代码中使用polyfills,表现形式和@babel/preset-latest同样,当使用ES6+语法及API时,在不支持的环境下会报错。
  2. "useBuiltIns":"entry"
    在项目入口引入一次(屡次引入会报错)

    import "@babel/polyfill"
    // or
    require("@babel/polyfill")

    插件@babel/preset-env会将把@babel/polyfill根据实际需求打散,只留下必须的,例如:

    // input file
    import "@babel/polyfill";
    // Out (different based on environment)
    import "core-js/modules/es6.promise";
    import "core-js/modules/es7.string.pad-start";
    import "core-js/modules/es7.string.pad-end";
    import "core-js/modules/es7.array.includes";
  3. "useBuiltIns":"usage"
    在文件须要的位置单独按需引入,能够保证在每一个bundler中只引入一份。例如:

    // In
    //a.js
    var a = new Promise();
    
    //b.js
    var b = new Map();
    // Out (if environment doesn't support it)
    import "core-js/modules/es6.promise";
    var a = new Promise();
    
    import "core-js/modules/es6.map";
    var b = new Map();
    
    // Out (if environment supports it)
    var a = new Promise();
    var b = new Map();

babel7以前的一些历史

bale7发布;能够说是对之前改变了很多,最为主要的是如下两点:

babel-preset-es20xx

babel-preset-es2015babel-preset-es2016babel-preset-es2017babel配合ECMA组委会给TC39的要求,但愿ECMA-262可以每一年都更新一个版本,因此每一年发了一个版本的话,那么babel就会把新的语法建立一个新的预设,以年份命名。

这样看似很好的,不过有一个问题,随着每一年的推动,开发者须要每年就在配置文件中添加一个当年的预设,因此把这些做为stage4之内的完成的ECMA-261提案集合到一个预设@babel/preset-env;而babel只要不停地更新这个预设就能够了。

stage的移除

以前提到了,关于TC39的提案进程,有的时候除了stage4的提案外,开发者还想使用其余的进度上的提案,babel使用了babel-preset-stage-0babel-preset-stage-1babel-preset-stage-2babel-preset-stage-3这四个预设分别对应四个阶段,

作法看似很好,一样有一个隐患,不少时候,开发者只想使用某一个阶段的提案,而不是把这个阶段的全部提案都引进来,因此babel7的作法是把这个stage-x的预设全都废弃,而是让开发者来进行本身手动将须要的对应阶段的插件引入便可,而不用采用预设的方案,由于预设就是插件的集合。

参考:
es简介译文
es个版本的增长项
es2015的
es6增长
es5增长
es和ecmascript关系
babel预设
babel翻译文档
babel使用实例
tc39的进程理解
plugins必知插件

相关文章
相关标签/搜索