博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Babel手册
阅读量:6413 次
发布时间:2019-06-23

本文共 5026 字,大约阅读时间需要 16 分钟。

介绍

Babel是一个工具链,主要用于将ECMAScript 2015+版本代码向后兼容 Javascript 语法,以便可以运行到旧版本浏览器或其他环境中。

作为一种语言,JavaScript在不断发展,新的标准/提案和新的特性层出不穷。在得到广泛普及之前,Babel能够让你提前(甚至数年)使用他们。

Babel 的三个主要处理步骤分别是: 解析(parse),转换(transform),生成(generate)。

  • 解析

将代码解析成抽象语法树(AST),每个js引擎(比如Chrome浏览器中的V8引擎)都有自己的AST解析器,而Babel是通过Babylon实现的。在解析过程中有两个阶段:词法分析和语法分析,词法分析阶段把字符串形式的代码转换为令牌(tokens)流,令牌类似于AST中节点;而语法分析阶段则会把一个令牌流转换成 AST的形式,同时这个阶段会把令牌中的信息转换成AST的表述结构。

  • 转换

在这个阶段,Babel接受得到AST并通过babel-traverse对其进行深度优先遍历,在此过程中对节点进行添加、更新及移除操作。这部分也是Babel插件介入工作的部分。

  • 生成 将经过转换的AST通过babel-generator再转换成js代码,过程就是深度优先遍历整个AST,然后构建可以表示转换后代码的字符串。

例如,Babel能够将新的ES2015箭头函数语法:

const square = n => n * n;复制代码

转译为:

const square = function square(n) {    return n * n;}复制代码

babel各个模块介绍

1.babel-core

babel的核心模块,包括一些核心api例如:transform。

/* * @param {string} code 要转译的代码字符串 * @param {object} options 可选,配置项 * @return {object} */babel.transform(code: string, options?: Object)    //返回一个对象(主要包括三个部分):{    generated code, //生成码    sources map, //源映射    AST  //即abstract syntax tree,抽象语法树}复制代码

更多知识点

一些使用babel插件的打包或构建工具都有使用到这个方法,下面是一些引入babel插件中的源码:

//gulp-babelconst babel = require('babel-core');/*some codes...*/module.exports = function (opts) {    opts = opts || {};	return through.obj(function (file, enc, cb) {        try {            const fileOpts = Object.assign({}, opts, {            	filename: file.path,            	filenameRelative: file.relative,            	sourceMap: Boolean(file.sourceMap),            	sourceFileName: file.relative,            	sourceMapTarget: file.relative            });            const res = babel.transform(file.contents.toString(), fileOpts);            if (res !== null) {            	//some codes            }        } catch (err) {            //some codes        }    }}//babel-loadervar babel = require("babel-core");/*some codes...*/var transpile = function transpile(source, options) {    //some code    try {        result = babel.transform(source, options);    } catch (error) {        //some codes    }    //some codes}//rollup-pugin-babelimport { buildExternalHelpers, transform } from 'babel-core';/*some codes...*/export default function babel ( options ) {    //some codes    return {        // some methods        transform ( code, id ) {            const transformed = transform( code, localOpts );            //some codes            return {            	code: transformed.code,            	map: transformed.map            };        }    }}复制代码

2.babel-cli

Babel的CLI是一种在命令行下使用Babel编译文件的简单方法。主要用于文件的输入输出。

全局安装

npm install -g babel-cli复制代码

我们可以这样编译我们第一个文件:

babel test.js//编译后的文件输出在终端复制代码
babel test.js -o test-out.js//编译后的文件输出在test-out.js文件中复制代码

在项目内运行 Babel CLI

尽管可以把Babel CLI全局安装在你的机器上,但是按项目逐个安装在本地会更好。 有两个主要的原因。

  • 1.在同一台机器上的不同项目或许会依赖不同版本的Babel并允许你有选择的更新。
  • 2.意味着对工作环境没有隐式依赖,让项目有很好的移植性并易于安装

将Babel CLI安装到本地可以运行:

npm install --save-dev babel-cli复制代码

现在可以不直接在命令行运行Babel了,取而代之我们将命令写在package.json的script里。

只需将"scirpts"字段添加到你的package.json文件内。

{    "scripts":{        "build": "babel src -d lib",        ...    },    ...}复制代码

现在可以在终端里运行:

npm run build复制代码

这将以与之前同样的方式运行Babel。

3.babel-node

babel-node是随babel-cli一起安装的,只要安装了babel-cli就会自带babel-node。 在命令行输入babel-node会启动一个REPL(Read-Eval-Print-Loop),这是一个支持ES6的js执行环境。

4.babel-register

babel-register字面意思能看出来,这是babel的一个注册器,它在底层改写了node的require方法,引入babel-register之后所有require并以.es6, .es, .jsx 和 .js为后缀的模块都会经过babel的转译。

//test.jsconst name = 'test';module.exports = () => {    const json = {name};    return json;};//main.jsrequire('babel-register');var test = require('./test.js');  //test.js中的es6语法将被转译成es5console.log(test.toString()); //通过toString方法,看看控制台输出的函数是否被转译/*    function () {        var json = { name: name };        return json;    }*/复制代码

5.babel-polyfill

babel-polyfill在代码中的作用主要是用已经存在的语法和api实现一些浏览器还没有实现的api,对浏览器的一些缺陷做一些修补。例如Array新增了includes方法,我想使用,但是低版本的浏览器上没有,引入babel-polyfill则帮我们添加了这些方法。

项目使用

1. .babelrc

babel所有的操作基本都会来读取这个配置文件,除了一些在回调函数中设置options参数的,如果没有这个配置文件,会从package.json文件的babel属性中读取配置。

2.plugins

babel中的插件,通过配置不同的插件才能告诉babel,我们的代码中有哪些是需要转译的。

3.presets

预设就是一系列插件的集合,就好像修图一样,把上次修图的一些参数保存为一个预设,下次就能直接使用。

// cnpm install -D babel-preset -env{    "presets": [        ["env", {            "targets": { //指定要转译到哪个环境                //浏览器环境                "browsers": ["last 2 versions", "safari >= 7"],                //node环境                "node": "6.10", //"current"  使用当前版本的node                            },             //是否将ES6的模块化语法转译成其他类型             //参数:"amd" | "umd" | "systemjs" | "commonjs" | false,默认为'commonjs'            "modules": 'commonjs',            //是否进行debug操作,会在控制台打印出所有插件中的log,已经插件的版本            "debug": false,            //强制开启某些模块,默认为[]            "include": ["transform-es2015-arrow-functions"],            //禁用某些模块,默认为[]            "exclude": ["transform-es2015-for-of"],            //是否自动引入polyfill,开启此选项必须保证已经安装了babel-polyfill            //参数:Boolean,默认为false.            "useBuiltIns": false        }]    ]}复制代码

关于最后一个参数useBuiltIns,有两点必须要注意:

  • 1.如果useBuiltIns为true,项目中必须引入babel-polyfill。
  • 2.babel-polyfill只能被引入一次,如果多次引入会造成全局作用域的冲突。

转载于:https://juejin.im/post/5cb5a2ecf265da036d79b143

你可能感兴趣的文章
dos2unix与unix2dos之学习记录
查看>>
java 小记
查看>>
步步为营 .NET 设计模式学习笔记 五、Prototype(原型模式)
查看>>
Building and Installing NetCDF on Windows
查看>>
如何让中间层MIDAS/DATASNAP支持大量的并发用户并且控制连接数量
查看>>
移动平台3G手机网站前端开发布局技巧汇总(转)
查看>>
多种方法实现div两列等高(收集整理)
查看>>
企业应用架构模式阅读笔记 - Martin Fowler
查看>>
PostgreSQL缓存
查看>>
iOS开发技巧 - 使用和定制开关控件(UISwitch)
查看>>
音乐闹钟
查看>>
JQuery模板插件jquery.tmpl-动态ajax扩展
查看>>
QT小滑块
查看>>
iis7.5 发布mvc出错的解决办法
查看>>
职称英语
查看>>
用JavaScript生成Android SDK的下载地址(4)——按“API Level”分类
查看>>
SQL Server 自动增长清零
查看>>
多核与云计算
查看>>
C++中的头文件和源文件
查看>>
SQLite在Android中使用
查看>>