babel-runtime和babel-polyfill两者区别优缺点
先说两种方式的原理:
babel-polyfill 使用场景
Babel 默认只转换新的 JavaScript 语法,而不转换新的 API。例如,Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转译。如果想使用这些新的对象和方法,必须使用 babel-polyfill,为当前环境提供一个垫片。它不会将代码编译成低版本的ECMAScript,他的原理是当运行环境中并没有实现的一些方法,babel-polyfill中会给做兼容
babel-runtime使用场景
将es6编译成es5去运行,前端可以使用es6的语法来写,最终浏览器上运行的是es5,Babel 转译后的代码要实现源代码同样的功能需要借助一些帮助函数,例如,{ [name]: 'JavaScript' } 转译后的代码如下所示
'use strict';
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
var obj = _defineProperty({}, 'name', 'JavaScript');
类似上面的帮助函数 _defineProperty 可能会重复出现在一些模块里,导致编译后的代码体积变大。Babel 为了解决这个问题,提供了单独的包 babel-runtime 供编译模块复用工具函数。
启用插件 babel-plugin-transform-runtime 后,Babel 就会使用 babel-runtime 下的工具函数,转译代码如下:
'use strict';
// 之前的 _defineProperty 函数已经作为公共模块 `babel-runtime/helpers/defineProperty` 使用
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var obj = (0, _defineProperty3.default)({}, 'name', 'JavaScript');
除此之外,babel 还为源代码的非实例方法(Object.assign,实例方法是类似这样的 "foobar".includes("foo"))和 babel-runtime/helps 下的工具函数自动引用了 polyfill。这样可以避免污染全局命名空间,非常适合于 JavaScript 库和工具包的实现。例如 const obj = {}, Object.assign(obj, { age: 30 }); 转译后的代码如下所示:
'use strict';
// 使用了 core-js 提供的 assign
var _assign = require('babel-runtime/core-js/object/assign');
var _assign2 = _interopRequireDefault(_assign);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var obj = {};
(0, _assign2.default)(obj, {
age: 30
});
优缺点:
babel-polyfill:通过向全局对象和内置对象的prototype上添加方法来实现,比如运行环境中不支持Array-prototype.find,引入polyfill,前端就可以放心的在代码里用es6的语法来写;但是这样会造成全局空间污染。比如像Array-prototype.find就不存在了,还会引起版本之前的冲突。不过即便是引入babel-polyfill,也不能全用,代码量比较大。
babel-runtime:不会污染全局对象和内置的对象原型。比如当前运行环境不支持promise,可以通过引入babel-runtime/core-js/promise来获取promise,或者通过babel-plugin-transform-runtime自动重写你的promise。但是它不会模拟内置对象原型上的方法,比如Array-prototype.find,就没法支持了,如果运行环境不支持es6,代码里又使用了find方法,就会出错,因为es5并没有这个方法。
transform-runtime只会对es6的语法进行转换,而不会对新api进行转换。
如果需要转换新api,就要引入babel-polyfill.
思考:babel-runtime 为什么适合 JavaScript 库和工具包的实现?
避免 babel 编译的工具函数在每个模块里重复出现,减小库和工具包的体积;
在没有使用 babel-runtime 之前,库和工具包一般不会直接引入 polyfill。否则像 Promise 这样的全局对象会污染全局命名空间,这就要求库的使用者自己提供 polyfill。这些 polyfill 一般在库和工具的使用说明中会提到,比如很多库都会有要求提供 es5 的 polyfill。在使用 babel-runtime 后,库和工具只要在 package.json 中增加依赖 babel-runtime,交给 babel-runtime 去引入 polyfill 就行了;
总结:
具体项目还是需要使用 babel-polyfill,只使用 babel-runtime 的话,实例方法不能正常工作(例如
"foobar".includes("foo"));JavaScript 库和工具可以使用 babel-runtime,在实际项目中使用这些库和工具,需要该项目本身提供 polyfill;
疑问:像 antd@2.x 这样的库使用了 babel-runtime,在实际项目中使用 antd@2.x,我们需要引入 babel-polyfill。但全部 polyfill 打包压缩下来也有 80kb 左右,其中很多 polyfill 是没有用到的,如何减少体积呢?手工一个个引入使用到的 polyfill,似乎维护成本太高!
babel-runtime和babel-polyfill两者区别优缺点的更多相关文章
- @babel/runtime 和 @babel/plugin-transform-runtime 两个的作用是什么
Babel 最基础的功能就是将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中. 最基础的依赖包也就是 ...
- Install fail! Error: [@@babel/runtime/core-js/object/keys]
1.Install fail! Error: [@@babel/runtime/core-js/object/keys] "@babel/runtime": "7.0.0 ...
- Error: Cannot find module '@babel/runtime/core-js/object/keys'(npm start报错)
1.问题描述: 在npm start启动react项目的时候,会出现Cannot find module '@babel/runtime/core-js/object/keys'的报错: 打开:项目根 ...
- Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' and Module not found: Error: Can't resolve '@babel/runtime/helpers/defineProperty'
These two mistakes are really just one mistake, This is because the following file @babel/runtime ca ...
- Babel插件:@babel/plugin-transform-runtime
一 概述 每个Babel编译后的脚本文件,都以导入的方式使用Babel的帮助函数,而不是每个文件都复制一份帮助函数的代码. 1 优点 (1)提高代码重用性,缩小编译后的代码体积. (2)防止污染全局作 ...
- 【Babel】293- 初学 Babel 工作原理
戳蓝字「前端技术优选」关注我们哦! 前言 babel Babel 对于前端开发者来说应该是很熟悉了,日常开发中基本上是离不开它的. 已经9102了,我们已经能够熟练地使用 es2015+ 的语法.但是 ...
- SVN和Git 介绍,区别,优缺点以及适用范围
SVN是Subversion的简称,是一个开放源代码的版本控制系统,支持大多数常见的操作系统.作为一个开源的版本控制系统,Subversion管理着随时间改变的数据.这些数据放置在一个中央资料档案库( ...
- OLEDB和ODBC的区别(优缺点)
ODBC是一种连接数据库的开放标准,OLEDB(对象链接和嵌入数据库)位于ODBC层与应用程序之间. 在你的ASP页面里,ADO是位于OLEDB之上的应用程序. 你的ADO调用先被送到OLEDB,然后 ...
- xml与json的原理,区别,优缺点.
1.定义介绍 (1).XML定义扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许 ...
随机推荐
- Codeforces Round #395 (Div. 2)(未完)
2.2.2017 9:35~11:35 A - Taymyr is calling you 直接模拟 #include <iostream> #include <cstdio> ...
- BZOJ 1037: [ZJOI2008]生日聚会Party [序列DP]
1037: [ZJOI2008]生日聚会Party Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2249 Solved: 1337[Submit] ...
- 2018/1/21 Netty通过解码处理器和编码处理器来发送接收POJO,Zookeeper深入学习
package com.demo.netty; import org.junit.Before;import org.junit.Test; import io.netty.bootstrap.Boo ...
- python爬虫(1)——urllib包
人生苦短,我用python! 一.关于爬虫 鉴于我的windos环境使用命令行感觉非常不便,也懒得折腾虚拟机,于是我选择了一个折中的办法--Cmder.它的下载地址是:cmder.net Cmder是 ...
- R语言-主成分分析
1.PCA 使用场景:主成分分析是一种数据降维,可以将大量的相关变量转换成一组很少的不相关的变量,这些无关变量称为主成分 步骤: 数据预处理(保证数据中没有缺失值) 选择因子模型(判断是PCA还是EF ...
- vs code 使用git
1.下载git https://git-scm.com/ 2. git 全局设置 git config --global user.name "xxxx" git config - ...
- java4 - 函数(方法)
一.学习大纲: 1. 定义函数可以将功能封装 2. 函数的级别都是同级别的,不能进行函数套用 3. 便于对该功能进行复用 4. 函数只有被调用才能被执行 5. 函数的出现提高了代码的复用性 6. 函数 ...
- js中判断数组中是否含有某个字符串方法
1.两个数组间互相校验 Var inArray = function(arr, item) { for(var i = 0; i < arr.length; i++) { if(arr[i] ...
- UVA-714 二分
把可能的进行二分判断,判断的时候尽量向右取,一直取到不能去为止,这样才有可能成功分割. 判断是否可以把up作为最大值的代码: bool judge(LL up){ if(up < Big) re ...
- Springdata mongodb 版本兼容 引起 Error [The 'cursor' option is required, except for aggregate with the explain argument
在Spring data mongodb 中使用聚合抛出异常 mongodb版本 为 3.6 org.springframework.dao.InvalidDataAccessApiUsageExce ...