• babel学习笔记


    babel: 把符合最新标准的js代码向下编译成现在随处可用的版本,还支持语法扩展,如支持React用的JSX语法,还支持用于静态类型检查的流式语法(Flow Syntax)。

    babel的一切都是简单的插件,你也可以利用babel创建自己的插件。

    babel自身被分解成了数个核心模块,任何人都可以利用它们来创建下一代的js工具(围绕着babel已涌现出了大规模和多样化的生态系统)。

    Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。如它能编译箭头函数语法,却无法编译Array.from()这个新的api。为了解决这个问题,我们使用一种叫做 Polyfill(代码填充,也可译作兼容性补丁) 的技术。 简单地说,polyfill 即是在当前运行环境中用来复制尚不存在的原生 api 的代码。 能让你提前使用还不可用的 APIs,Array.from 就是一个例子。

    js发展史:

    1996年,网景浏览器,网景把javascript提交给 ECMA International(欧洲计算机制造商协会) 进行标准化,并最终确定出新的语言标准,它就是 ECMAScript。自此,ECMAScript 成为所有 JavaScript 实现的基础,不过,现实中我们只用 ECMAScript 称呼标准,平时都还是使用 JavaScript 来称呼这个语言。
    标准(Standard): 用于定义与其他事物区别的一套规则。
    实现(Implementation): 某个标准的具体实施/真实实践。

    1996--2011年,相继发布了ECMAScript3,(ECMAScipt4由于太过激进而被抛弃),ECMAScript5,但由于现实中的很多实现和标准大相径庭,大部分开发者依然写着ECMAScript3风格的代码。 

    2012年,由于开始停止对旧版浏览器的支持,用ECMAScript5(ES5)编写代码变得可行。并且新的ES6标准开始启动。

    2015 年,负责制定 ECMAScript 规范草案的委员会 TC39 决定将定义新标准的制度改为一年一次(所以开始以年份来命名ECMAScript标准了),这意味着每个新特性一旦被批准就可以添加,而不像以往一样,规范只有在整个草案完成,所有特性都没问题后才能被定稿。因此,ES6在2015年6月份公布之前又被重命名为了 ECMAScript 2015(ES2015)

    2016年,提议中的新的js语法ES2016,或称为ES7。

    2017年,提议中的新的js语法ES2017,或称为ES8,如async, await。

    js提案要被正式采纳必须经过5(0-4)个阶段,相继通过各个阶段,最终在阶段4被标准正式采纳。

    .babelrc:

    babel的配置文件,用来让babel做你要它做的事情的配置文件,存放在项目的根目录下,用来设置转码规则和插件。在 babel 6 里,执行 babel test.js,只会输出原样的文本,因为 babel 不再包含任何 transform 功能,babel 6 里把它们作为插件(plugin)分割出去,需要我们自己配置插件,.babelrc文件内容为:

    {
      "presets": [],   // 转码规则
      "plugins": []    // 插件
    }

    比如要使用es6的箭头函数,必须配置"plugins": ["transform-es2015-arrow-functions"]。基本上 ES6/ES7 的各种功能,babel 都提供了相应的插件用于转换,但如果我们要一个一个配置 – 那就太恼人了。所以 babel 还提供了一个方法:presets。我们不妨把 presets 理解为套餐,不同套餐有不同的插件组合,比如 ES2015 preset 里打包了所有用于转换 ES2015 代码的插件,React preset 则打包了转换 react.js jsx 语法的插件。

    转码规则可以根据需要按照:

    # ES2015转码规则
    $ npm install --save-dev babel-preset-es2015  //包含所有es2015的特性
    
    # react转码规则
    $ npm install --save-dev babel-preset-react
    
    # ES7不同阶段语法提案的转码规则(共有4个阶段),选装一个
    $ npm install --save-dev babel-preset-stage-0  //包含了async,await等
    $ npm install --save-dev babel-preset-stage-1
    $ npm install --save-dev babel-preset-stage-2
    $ npm install --save-dev babel-preset-stage-3

    然后,将这些规则加入.babelrc:

    {
        "presets": [
          "es2015",
          "react",
          "stage-2"
        ],
        "plugins": []
      }

    以下所有Babel工具和模块的使用,都必须先写好.babelrc。也可以把内容写进package.json文件里:

    "babel": {
        "presets": [
          "react",
          "node5",
          "stage-0"
        ],
         "plugins": []
    },

    babel-cli,babel-node:

    全局按照babel-cli,就可以在命令行下使用Babel编译文件了,如babel src -d lib (把src目录整个编译成一个新的目录)或babel example.js -o compiled.js (把example.js编译后的结果写入到compiled.js)。但是不推荐全局安装,导致项目产生了对环境的依赖,另一方面,这样做也无法支持不同项目使用不同版本的Babel。一般在项目中安装babel: npm install babel-cli --save-dev ,把命令写在npm scripts里,如"scripts": {"build": "babel src -d lib"},然后就可以在终端里运行npm run build。

    babel-node不用单独安装,而是随babel-cli一起安装。babel-node命令,它近似于 node,只不过它在运行代码前会预先编译 ES2015 的代码。提供一个支持ES6的REPL环境。它支持Node的REPL环境的所有功能,而且可以直接运行ES6代码或脚本文件。

    把npm scripts改写成"scripts": {"build": "babel-node scripts.js"},这样script.js本身就不用做任何转码处理。

    babel-register:

    运行babel的另一个方法,只需要引入文件就可以运行 Babel,或许能更好地融入你的项目设置。babel-register模块改写require命令,为它加上一个钩子。此后,每当使用require加载.js、.jsx、.es和.es6后缀名的文件,就会先用Babel进行转码。如创建一个register.js文件:

    require("babel-register")
    require("./index.js")

    这样做就可以把 Babel注册到 Node 的模块系统中并开始编译其中 require 的所有文件。这样执行命令node register.js就可以运行的就是编译后的index.js文件了。需要注意的是,babel-register只会对require命令加载的文件转码,而不会对当前文件转码。另外,由于它是实时转码,所以只适合在开发环境使用。

    babel-core:

    以编程的方式来使用 Babel,如果某些代码需要调用Babel的API进行转码,就要使用babel-core模块。

    var babel = require('babel-core');
    // 字符串转码
    babel.transform('code();', options);
    // => { code, map, ast }
    // 文件转码(异步)
    babel.transformFile('filename.js', options, function(err, result) {
      result; // => { code, map, ast }
    });
    // 文件转码(同步)
    babel.transformFileSync('filename.js', options);
    // => { code, map, ast }

    babel-polyfill:

    Babel默认只转换新的JavaScript句法(syntax),而不转换新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。如果想让这些方法运行,必须使用babel-polyfill,为当前环境提供一个垫片。

    要使用 Babel polyfill,首先用 npm 安装它:npm install --save babel-polyfill,然后只需要在文件顶部导入 polyfill 就可以了:import 'babel-polyfill'或是在webpack.config.js中加入babel-polyfill到你的入口数组:entry:["babel-polyfill","./app/js"]

    babel-runtime:

    与 babel-polyfill 一样,babel-runtime 的作用也是模拟 ES2015 环境。只不过,babel-polyfill 是针对全局环境的引入它的,babel-runtime 更像是分散的 polyfill 模块,我们可以在自己的模块里单独引入,比如 require(‘babel-runtime/core-js/promise’) ,它们不会在全局环境添加未实现的方法,只是,这样手动引用每个 polyfill 会非常低效。我们借助 Runtime transform 插件来自动化处理这一切。安装:npm install --save-dev babel-plugin-transform-runtime    npm install --save babel-runtime; 配置.babelrc: "plugins":["transform-runtime"],这样Babel会把这样的代码:

    class Foo {
      method() {}
    }

    编译成:

    import _classCallCheck from "babel-runtime/helpers/classCallCheck";
    import _createClass from "babel-runtime/helpers/createClass";
    
    let Foo = function () {
      function Foo() {
        _classCallCheck(this, Foo);
      }
      _createClass(Foo, [{
        key: "method",
        value: function method() {}
      }]);
      return Foo;
    }();

    至于要用 babel-polyfill 还是 babel-runtime,则需要根据具体需求。举个例子,如果一个库里引用了 babel-polyfill,别人的库也引用了 babel-polyfill,我们很可能会跑两个 babel-polyfill 实例,这里,使用 babel-runtime 会更合适。

    手动指定插件:

    你可以安装一些别的插件,配置.babelrc的plugins,这样能让你对正在使用的转换器进行更细致的控制。如babel-plugin-transform-es2015-classes插件。插件列表可参考babel官方网址

    插件选项:很多插件也有选项用于配置他们自身的行为。 例如,很多转换器都有“宽松”模式,通过放弃一些标准中的行为来生成更简化且性能更好的代码。如"plugins":[ ["transform-es2015-classed", {"loose":true}] ]。

    基于环境自定义babel:

    Babel 插件解决许多不同的问题。 其中大多数是开发工具,可以帮助你调试代码或是与工具集成。 也有大量的插件用于在生产环境中优化你的代码。因此,想要基于环境来配置 Babel 是很常见的。你可以轻松的使用 .babelrc 文件来达成目的。

    {
        "presets": [...],
        "plugins": [...],
        "env": {
          "development": {
            "plugins": [...]
          },
           "production": {
            "plugins": [...]
          }
        }
     }

    Babel 将根据当前环境来开启 env 下的配置。当前环境可以使用 process.env.BABEL_ENV 来获得。 如果 BABEL_ENV 不可用,将会替换成 NODE_ENV,并且如果后者也没有设置,那么缺省值是"development"

    手动指定插件?插件选项?环境特定设置?所有这些配置都会在你的项目里产生大量的重复工作。为此可以创建自己的预设并发布,使用时直接安装就可以了,比如 babel-preset-airbnb

    Babel和其他工具:

    以eslint为例,eslint是最流行的语法检查工具之一。首先安装 eslint 和 babel-eslint,然后创建或使用项目现有的 .eslintrc 文件并设置 parser 为 babel-eslint,现在添加一个 lint 任务到 npm 的 package.json 脚本中就可以了,"scripts": {"lint": "eslint my-files.js"}。

    webpack中定义babel-loader:

    webpack.config.js中的loaders配置参考:

    loaders: [     
      {
          test: /.jsx?$/,
          loader: 'babel-loader',
          include: [
              path.resolve(__dirname, '../src'),
          ],
          query: {
              babelrc: false,
              presets: [
                  'react',
                  'es2015',
                  'stage-0',
              ],
              plugins: [
                  'transform-runtime'
               ]
          }
      }
    ]
  • 相关阅读:
    Django—使用后台管理Models
    Django—开发具体流程
    Sqlite—数据库管理与表管理
    Sqlite—数据类型
    Python—实现钉钉后台开发
    Xdebug文档(一)基本特性
    FHS定义的Linux目录树
    【转】给Windows + Apache 2.2 + PHP 5.3 安装PHP性能测试工具 xhprof
    【转】UTF-8汉字正则表达式
    【转】Nginx区分PC或手机访问不同网站
  • 原文地址:https://www.cnblogs.com/yigeqi/p/6953037.html
Copyright © 2020-2023  润新知