热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

你需要掌握的babel知识都在这里

随着ES6以及后面版本的问世,确实给前端JavaScript增添了不少活力,层出不穷的高级语法不仅提升编码效率,还使得前端的编码风格越来越

随着ES6以及后面版本的问世,确实给前端Javascript增添了不少活力,层出不穷的高级语法不仅提升编码效率,还使得前端的编码风格越来越靠近贴近主流。然而这些高级语法在有些浏览器上却运行不了,是因为浏览器还没法编译js的高级语法导致出现兼容性问题,需要将这些高级语法编译成浏览器能够运行的低版本语法。今天讲解的babel就是来解决这个js兼容问题的。

Babel,又名Babel.js。 是一个用于web 开发,且自由开源的Javascript 编译器、转译器。 Babel 使软件开发者能够以偏好的编程语言或风格来写作源代码,并将其利用Babel 翻译成Javascript。 Babel 是一个常用来使用最新的Javascript 语言特性的工具。——维基百科

babel官网

前置知识


babel编译流程

babel其实就是将源码转换成目标源码的一个过程,大致分为三步

  • parse: 通过parser把源码转成抽象ast语法树
  • transform: 循环遍历ast,通过transform的能力对其进行语法转换
  • generate: 根据转换后的源码生产目标源码

主要依赖库介绍

@babel-core:babel核心编译库,它能够进行语法、语义、词法分析,生成抽象语法树
@babel-cli:负责命令相关的功能,提供 bebel 命令
@babel/preset-env:ES6稳定语法transform插件的集合
@babel/runtime: 运行时,配合transform-runtime
@babel/plugin-transform-runtime:polyfill垫片防止污染全局变量(第三方库必须得接入)
@babel/polyfill:高级语法兼容解决方案依赖

学习babel,你主要掌握一下三个模块就差不多了:

  • 1、环境搭建,基本配置
  • 2、babel-polyfill
  • 3、babel-runtime

基本配置


搭建一个简单的项目

┌-- src
┆ └--index.js
├-- .babelrc
└-- package.json

配置scripts命令

# package.json
{..."scripts": {"babel": "babel src/index.js --out-dir dist"},...
}

安装

开发依赖

yarn add @babel/cli @babel/core @babel/plugin-transform-runtime @babel/preset-env -D

生产依赖

yarn add @babel/polyfill @babel/runtime -S

配置.babelrc

{"presets": [["@babel/preset-env"]],"plugins": []
}

到这里一个最基础版本的babel就配置好了,运行看看
src/index.js

const sum = (a, b) => a + b;

输出
dist/index.js

"use strict";var sum = function sum(a, b) {return a + b;
};

证明babel已经可以将箭头函数转换为 function 函数了,大功告成!先别高兴太早,插播一段解释。。。。。。。

1、解释一下@babel/preset-env
这个是ES6稳定语法编译插件的集合,什么意思?就是除掉一小部分高级语法(无法用js完整表示)以外的ES6语法转换成低版本js的插件的集合。
举例:如果不用预设,上面src/inex.js中的箭头函数得单独安装@babel/plugin-transform-arrow-functions插件来完成转译

{"presets": [], "plugins": ["@babel/plugin-transform-arrow-functions"],//"targets": "last 2 Chrome versions"
}

也是可以正常转译箭头函数,也就是说在babel中一种语法就得需要对应一个插件来转译,这里所说的@babel/preset-env预设就是很多稳定语法转译成低版本js插件的集合,目的是方便使用,减少配置成本。
2、这里再补充一下几个官方的预设
@babel/preset-react:用来编译jsx语法
@babel/preset-typescript:用来将ts文件转成js文件
@babel/preset-flow:用来将使用flow类型约束的文件转成js文件
3、既然babel是将高级语法转成低版本语法来做兼容处理,那到底要转到多低的版本呢???
@babel/preset-env会根据配置文件中的targets属性来生成插件列表后编译,在浏览器或electron中,官方还是推荐用.browserslistrc来配置目标环境。如果babel配置文件没有设置targetsignoreBrowserslistConfig,@babel/preset-env会使用默认的browserslist配置源(**> 0.5%, last 2 versions, Firefox ESR, not dead**)

好了,来继续,来试试promise高级语法转译情况
src/index.js

const sum = (a, b) => a + b;
// 新的 API
Promise.resolve(100).then((data) => data);

编译后输出

"use strict";
var sum = function sum(a, b) {return a + b;
}; // 新的 API
Promise.resolve(100).then(function (data) {return data;
});

发现Promsie根本就没有转译,也就是说@babel/preset-env预设没法转译promsie,怎么解决???
引入下一个知识点,@babel/polyfill,简称 “垫片”,说白了就是用这个来抹平部分高级语法的兼容问题

@babel/polyfill 垫片

@babel/polyfill其实是一个空壳,他当中包含 core-jsregenerate,真正起作用的是这两个依赖包

使用

在入口文件的顶部引入

import "@babel/polyfill";

执行编译,输出,都正常了

但是@babel/polyfill89.4kb完全引入了,而这里只需要promsie对应的垫片就OK了,造成编译出来的文件内存很大,又是一个头疼的问题来了!!!

官方出了解决方案,Babel@7.4.0版本之前,还是得用上面这种全量引入的方式,之后,可以分开引入

import "core-js/stable";
import "regenerator-runtime/runtime";

这也差不多,没多大效果,那有没有一种自动按需引入的解决方案呢?
要说还得看官方,这不方案就来了吗

{ "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", "corejs": "3" } ] ]
}

配置完后,编译,输出

"use strict";require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
var sum = function sum(a, b) {return a + b;
}; // 新的 API
Promise.resolve(100).then(function (data) {return data;
});

完美解决!!!

到这里,如果自己的业务项目配置到此就结束了
如果是开发第三方依赖包,还得继续往下看

@babel/plugin-transform-runtime

咱们不解释为啥,先看使用了@babel/plugin-transform-runtime插件和没使用输出的代码。
src/index.js

class Test {}

未使用的输出情况

"use strict";require("core-js/modules/es.object.define-property.js");function _defineProperties(target, props) { for (var i = 0; i });

使用后的输出情况

"use strict";var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));var Test = /*#__PURE__*/(0, _createClass2["default"])(function Test() {(0, _classCallCheck2["default"])(this, Test);
});

从两段输出代码可以看出,后一种是用变量来储存插件的方法,而且是采用抽离公共代码的helper文件导出方法的形式,而前一种则是把方法直接编译到了文件内,试想一下会出什么问题?

如果一个项目有多个地方用到了class类,转译时每个文件都要多出这段代码,造成严重的代码冗余,还有一点,直接将方法编译到文件会污染文件的全局环境,尤其是作为第三方类库提供给别人使用时,很可能被覆盖掉,应该避免不必要的冲突

@babel/runtime 和 @babel/plugin-transform-runtime这两个插件要配合使用,得同时安装

{"presets": [["@babel/preset-env",{"useBuiltIns": "usage","corejs": 3}]],"plugins": [["@babel/plugin-transform-runtime",{"absoluteRuntime": false,"corejs": 3,"helpers": true,"regenerator": true,"useESModules": false}]]
}

结论:开发类库用polyfill + runtime,公司业务项目用polyfill就行了

完结


推荐阅读
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
author-avatar
o0沢田纲吉0o
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有