github.com/zloirock/co… 原文连接javascript
通过一年半的开发,数十个版本,许多不眠之夜,core-js@3
终于发布了。这是 core-js
和 babel 补丁相关的功能的最大的一次变化。html
什么是 core-js
?java
core-js
的导入它是最广泛、最流行给 JavaScript 标准库打补丁的方式,可是有很大一部分开发者并不知道他们间接的使用了core-js
🙂node
core-js
是我本身爱好的项目,没有给我带来任何利润。它花了我很长的时间,真的很昂贵:为了完成 core-js@3
,我在几个月以前已经离开个人工做。这个项目对许多人和公司起到了促进做用。由于这些,筹集资金去支持 core-js
的维护是说得通的。git
若是你对 core-js
感兴趣或者在你天天的工做中有使用到,你能够在 Open Collective 或者 Patreon 成为赞助者。es6
你能够给我提供一个好的工做,和我如今作的相关的。github
或者你能够以另外一种方式贡献,你能够帮助去改进代码、测试或者文档(如今,core-js
的文档还很糟糕!)。web
core-js@3
有哪些变化?因为如下两个缘由,这个版本包含丰富的、新的 JavaScript 补丁:chrome
core-js
只在 major(主)版本更新时才有 break changes,即便须要和提案的内容对齐。core-js@2
在一年半前已经进入功能冻结阶段了;全部新的功能只可以添加到 core-js@3
这个分支。稳定的 ECMAScript 功能在 core-js
中已经几乎彻底支持有很长一段时间了,除此以外,core-js@3
引进了一些新功能:npm
@@isConcatSpreadable
和 @@species
,给全部使用他们的方法。Array.prototype.flat
和 Array.prototype.flatMap
( core-js@2
针对 Array.prototype.flatten
这个老版本的提案提供了补丁)。Object.fromEntries
方法Symbol.prototype.description
访问器一些在 ES2016-ES2019 中做为提案被接受且已经使用很长时间的功能,如今被标记为稳定:
Array.prototype.includes
和 TypedArray.prototype.includes
方法( ESMAScript 2016 )Object.values
和 Object.entries
方法( ECMAScript 2017 )Object.getOwnPropertyDescriptors
方法 ( ECMAScript 2017 )String.prototype.padStart
和 String.prototype.padEnd
方法( ECMAScript 2017 )Promise.prototype.finally
方法( ECMAScript 2018 )Symbol.asyncIterator
知名标志( ECMAScript 2018 )Object.prototype.__define(Getter|Setter)__
和 Object.prototype.__lookup(Getter|Setter)__
方法( ECMAScript 2018 )String.prototype.trim(Start|End|Left|Right)
方法( ECMAScript 2019 )修复了针对浏览器的许多问题,例如,Safari 12.0 Array.prototype.reverse
bug 已经被修复了。
除了上文提到的支持内容,core-js@3
如今还支持下面的 ECMAScript 提案:
globalThis
stage 3( 如今是 stage 4 )的提案 - 以前,已经有了 global
和 System.global
Promise.allSettled
stage 2( 如今是 stage 4 )提案Set
方法 stage 2 提案:
String.prototype.replaceAll
stage 1( 如今是 stage 3 ) 提案String.prototype.codePoints
stage 1 提案Array.prototype.last(Item|Index)
stage 1 提案compositeKey
和 compositeSymbol
方法 stage 1 提案Number.fromString
stage 1 提案Math.seededPRNG
stage 1 提案Promise.any
(合并的错误) stage 0( 如今是stage 3 )提案一些提案的变化很大,core-js
也将相应的更新:
String.prototype.matchAll
stage 3 提案许多有用的功能被添加到这个类别中。
最重要的一个是 URL
和 URLSearchParams
。他是最受欢迎的功能请求之一。增长 URL
和 URLSearchParams
,并保证他们最大限度的符合规范,保持源代码足够紧凑来支撑任何环境是 core-js@3
开发中最困难的任务之一。
core-js@3
包函在JavaScript中建立微任务( microtask )的标准方法:queueMicrotask
。core-js@2
提供了 asap
函数,提供了一样功能的老的提案。queueMicrotask
被定义在 HTML 标准中,它已经可以在现代浏览器好比 Chromium 或者 NodeJS 中使用。
另外一个受欢迎的功能请求是支持 DOM集合的 .forEach
方法。因为 core-js
已经针对DOM集合迭代器作了polyfill,为何不给 节点列表
和 DOMTokenList
也增长 .forEach
呢?
Reflect.enumrate
由于他已经从标准中移除了System.global
和 global
如今他们已经被 globalThis
代替Array.prototype.flatten
如今被 Array.prototype.flat
代替asap
被 queueMicrotask
代替Error.isError
被撤销很长时间了RegExp.escape
好久以前被拒绝了Map.prototype.toJSON
和 Set.prototype.toJSON
也是好久前被拒绝了CSSRuleList
,MediaList
,StyleSheetList
。许多年前,我开始写一个库,他是个人JavaScript程序的核心:这个库包函 polyfills 和一些我须要的工具函数。一段时间后,这个库以 core-js
命名发布。我认为如今大多数 core-js
用户不须要非标准的 core-js
功能,他们大多已经在早期版本移除了,如今是时候将剩余部分从 core-js
中移除。从这个版本开始,core-js
能够被称为 polyfill 了。
一个issue里提了 core-js
包的很大( ~2MB ),有不少重复文件。由于这个缘由,core-js
分红了3个包:
core-js
定义全局的 polyfills。( ~500KB,压缩而且 gzipped 处理后 40KB )core-js-pure
,提供了不污染全局变量的 polyfills。它和 core-js@2
中的 core-js/library
至关。(~440KB)core-js-bundle
:定义了全局填充的打包版本core-js
的早期版本中,稳定的 ECMAScript 功能和 ECMAScript 提案的 polyfill 模块化须要分别加 es6.
和 es7.
前缀。这是在 2014 年作的决定,那时将 ES6 以后的全部功能都视为 ES7。在 core-js@3
中全部稳定的 ECMAScript 功能都增长 es.
前缀,ECMAScript 提案增长 esnext.
前缀。
几乎全部的 CommonJS 入口都改变了。core-js@3
相比于 core-js@2
有更多的入口:这带来的最大限度的灵活性,使你可以仅仅引入你的应用须要的依赖。
这里是一些例子关于如何使用新的入口:
// 使用 `core-js` 所有功能打补丁:
import "core-js";
// 仅仅使用稳定的 `core-js` 功能 - ES 和 web 标准:
import "core-js/stable";
// 仅仅使用稳定的 ES 功能
import "core-js/es";
// 若是你想用 `Set` 的补丁
// 全部 `Set`- ES 提案中,相关的功能:
import "core-js/features/set";
// 稳定的 `Set` ES 功能和来自web标准的功能
// (DOM 集合迭代器)
import "core-js/stable/set";
// 只有 `Set` 所需的稳定的 ES 功能
import "core-js/es/set";
// 与上面一致,但不会污染全局命名空间
import Set from "core-js-pure/features/set";
import Set from "core-js-pure/stable/set";
import Set from "core-js-pure/es/set";
// 仅仅为须要的方法打补丁
import "core-js/feature/set/intersection";
import "core-js/stable/queque-microtask";
import "core-js/es/array/from";
// 为 reflect metadata 提案打补丁
import "core-js/proposals/reflect-metadata";
// 为全部 stage 2+ 的提案打补丁
import "core-js/stage/2";
复制代码
core-js
polyfill 可以 配置侵入等级。若是你认为有些情境 core-js
功能检测侵入性太强,原生实现对你来讲已经足够,或者一个错误的实现没有被 core-js
检测到,你能够修改 core-js
的默认行为。
若是没法安装规范的每一个细节实现某个功能,core-js
增长了一个 .sham
属性,例如,IE11中 Symbol.sham
是 true
。
再也不有 LiveScript! 当我开始写 core-js
时,我主要使用的是 LiveScript ;一段时间后,我用 JavaScript 重写了所有的 polyfills 。在 core-js@2
中测试和帮助的工具函数仍然使用 LiveScript :它是很是有趣的像 CoffeeScript 同样的语言,有强大的语法糖使你可以写很是紧凑的代码,可是它几乎已经死了。除此以外,它也是为 core-js
贡献的屏障,由于大多数 core-js
用户不知道这个语言。core-js@3
测试和工具函数使用现代 ES 语法:它将成为为 core-js
贡献的好时机🙂。
对于大多数用户,为了优化 core-js
导入,我建议使用 babel。固然,有些状况下 core-js-builder
仍然有用。如今它支持 target
参数,使用带有目标引擎的浏览器列表
查询 - 你可以建立一个 bundle,仅仅包含目标引擎须要的 polyfills。对于这种状况,我作了 core-js-compat
,更多关于它的信息,你可以从 这篇文章的 @babel/preset-env
部分了解到。
这仅仅是冰山一角,更多的变化在内部。更多关于 core-js
变化能够在 changelog 中找到。
正如上文提到的,babel
和 core-js
是紧密集成的:babel
提供了优化 core-js
优化导入的可能性。core-js@3
开发中很重要的一部分是改进 core-js
相关的 babel
功能(看这个PR)。这些变化在 Babel 7.4.0 发布了。
@babel/polyfill
是一个包裹的包,里面仅仅包含 core-js
稳定版的引入(在Babel 6 中也包含提案)和 regenerator-runtime/runtime
,用来转译 generators 和 async 函数。这个包没有提供从 core-js@2
到 core-js@3
平滑升级路径:由于这个缘由,决定弃用 @babel/polyfill
代之以分别引入须要的 core-js
和 regenerator-runtime
。
原来
import "@babel/polyfill";
复制代码
如今使用两行代替:
import "core-js/stable";
import "regenerator-runtime/runtime";
复制代码
别忘记直接安装这两个依赖!
npm i --save core-js regenerator-runtime
复制代码
@babel/preset-env
有两种不一样的模式,经过 useBuiltIns
选项:entry
和 usage
优化 core-js
的导入。
Babel 7.4.0 引入了两种模式的共同更改,以及每种模式的特定的修改。
因为如今 @babel/preset-env
支持 core-js@2
和 core-js@3
,所以 useBuiltIns
须要新的选项 -- corejs
,这个选项用来定义使用 core-js
的版本(corejs: 2
或者 corejs: 3
)。若是没有设置,corejs: 2
是默认值而且会有警告提示。
为了使 babel 支持未来的次要版本中引入的 core-js
的新功能,你能够在项目中定义明确的次要版本号。例如,你想使用 core-js@3.1
使用这个版本的新特性,你能够设置 corejs
选项为 3.1
:corejs: '3.1'
或者 corejs: {version: '3.1'}
。
@babel/preset-env
最重要的一个功能就是提供不一样浏览器支持特性的数据来源,用来肯定是否须要 core-js
填充某些内容。 caniuse
,mdn
和 compat-table
是很好的教育资源,可是并不意味着他们可以做为数据源被开发者使用:只有 compat-table
包函好的 ES 相关数据集,它被 @babel/preset-env
使用,可是仍有些限制:
它包含的数据仅仅关于 ECMAScript 特性和提案,和 web 平台特性例如 setImmediate
或者 DOM 集合迭代器没有关系。因此直到如今,@babel/preset-env
仍然经过 core-js
添加所有的 web 平台特性即便他们已经支持了。
它他不包含任何浏览器(甚至是严重的)bug 信息:例如,上文提到的在 Safari 12 中 Array#reverse
,可是 compat-table
并无将它标记为不支持。另外一方面,core-js
已经修复了这个错误实现,可是由于 compat-table
关系,并不能使用它。
它仅包函一些基础的、幼稚的测试,没有检查功能在真实环境下是否能够正常工做。例如,老版本 Safari 的破坏的迭代器没有 .next
方法,可是 compat-table
代表 Safari 支持,由于它用 typeof
方法检测迭代器方法返回了 "function"
。一些像 typed arrays 的功能几乎没有覆盖。
compat-table
不是为了向工具提供数据而设计的。我是 compat-table
的维护者之一,可是其余的维护者反对为维护这个功能。
由于这个缘由,我建立了 core-js-compat
:它提供了对于不一样浏览器 core-js
模块的必要性数据。当使用 core-js@3
时,@babel/preset-env
将使用新的包取代 compat-table
。请帮助咱们测试并提供缺乏的引擎的数据的映射关系!😊。
在 Babel 7.3 以前,@babel/preset-env
有一些与 polyfills 注入顺序有关的问题。从 7.4.0开始,@babel/preset-env
只按推荐顺序增长须要的 polyfills 。
useBuiltIns: entry
with corejs: 3
当使用这个选项时,@babel/preset-env
代替直接引用 core-js
而是引入目标环境特定须要的模块。
在这个变化前,@babel/preset
仅替换 import '@babel/polyfill'
和 import 'core-js'
,他们是同义词用来 polyfill 全部稳定的 JavaScript 特性。
如今 @babel/polyfill
弃用了,当 corejs
设置为 3 时 @babel/preset-env
不会转译他。
core-js@3
中等价替换 @babel/polyfill
是
import "core-js/stable";
import "regenerator-runtime/runtime";
复制代码
当目标浏览器是 chrome 72
时,上面的内容将被 @babel/preset-env
转换为
import "core-js/modules/es.array.unscopables.flat";
import "core-js/modules/es.array.unscopaables.flat-map";
import "core-js/modules/es.object.from-entries";
import "core-js/modlues/web.immediate";
复制代码
当目标浏览器是 chrome 73
(它彻底支持 ES2019 标准库),他将变为不多的引入:
import "core-js/modules/web.immediate";
复制代码
自从 @babel/polyfill
被弃用,转而使用分开的 core-js
和 regenerator-runtime
,咱们可以优化 regenerator-runtime
的导入。由于这个缘由,若是目标浏览器原生支持 generators ,那么 regenerator-runtime
的导入将从源代码中移除。
如今,设置 useBuiltIns: entry
模式的 @babel/preset-env
编译全部可以得到的 core-js
入口和他们的组合。这意味着你可以自定义,经过使用不一样的 core-js
入口,它将根据的目标环境优化。
例如,目标环境是 chrome 72
,
import "core-js/es";
import "core-js/proposals/set-methods";
import "core-js/features/set/map";
复制代码
将被替换为
import "core-js/modules/es.array.unscopables.flat";
import "core-js/modules/es.array.unscopables.flat-map";
import "core-js/modules/es.object.from-entries";
import "core-js/modules/esnext.set.difference";
import "core-js/modules/esnext.set.intersection";
import "core-js/modules/esnext.set.is-disjoint-from";
import "core-js/modules/esnext.set.is-subset-of";
import "core-js/modules/esnext.set.is-superset-of";
import "core-js/modules/esnext.set.map";
import "core-js/modules/esnext.set.symmetric-difference";
import "core-js/modules/esnext.set.union";
复制代码
useBuiltIns: usage
with corejs: 3
当使用这个选项时,@babel/preset-env
在每一个文件的开头引入目标环境不支持、仅在当前文件中使用的 polyfills。
例如,
const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
复制代码
当目标环境是老的浏览器例如 ie 11
,将转换为
import "core-js/modules/es.array.includes";
import "core-js/modules/es.array.iterator";
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.set";
const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
复制代码
当目标是 chrome 72
时不须要导入,由于这个环境须要 polyfills:
const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
复制代码
Babel 7.3 以前,useBuiltIns: usage
不稳定且不是足够可靠:许多 polyfills 不包函,而且添加了许多不是必须依赖的 polyfills。在 Babel 7.4 中,我尝试使它理解每种可能的使用模式。
在属性访问器、对象解构、in
操做符、全局对象属性访问方面,我改进了肯定使用哪一个 polyfills 的技术。
@babel/preset-env
如今注入语法特性所需的 polyfills:使用 for-of
时的迭代器,解构、扩展运算符和 yield
委托;使用动态 import
时的 promises,异步函数和 generators,等。
Babel 7.4 支持注入提案 polyfills。默认,@babel/preset-env
不会注入他们,可是你可以经过 proposals
标志设置:corejs: { version: 3, proposals: true }
。
当使用 core-js@3
时, @babel/transform-runtime
如今经过 core-js-pure
(core-js
的一个版本,不会污染全局变量) 注入 polyfills。
经过将 @babel/transform-runtime
设置 corejs: 3
选项和建立 @babel/runtime-corejs3
包,已经将 core-js@3
和 @babel/runtime
集成在一块儿。可是这将带来什么好处呢?
@babel/runtime
的一个受欢迎的 issue 是:不支持实例方法。从 @babel/runtime-corejs3
开始,这个问题已经解决。例如,
array.includes(something);
复制代码
将被编译为
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
_includesInstanceProperty(array).call(array, something);
复制代码
另外一个值得关注的变化是支持 ECMAScript 提案。默认状况下的,@babel/plugin-transform-runtime
不会为提案注入 polyfills 并使用不包含提案的入口。可是正如你在 @babel/preset-env
中作的那样,你能够设置 proposals
标志去开启:corejs: { version: 3, proposals: true }
。
没有 proposals
标志,
new Set([1, 2, 3, 2, 1]);
string.matchAll(/something/g);
复制代码
将被编译为:
import _Set from "@babel/runtime-corejs/core-js-stable/set";
new _set([1, 2, 3, 2, 1]);
string.matchAll(/something/g);
复制代码
当设置 proposals
后,将变为:
import _Set from "@babel/runtime-corejs3/core-js/set";
import _matchAllInstanceProperty from "@babel/runtime-corejs/core-js/instance/match-all";
new _Set([1, 2, 3, 2, 1]);
_matchAllInstanceProperty(string).call(string, /something/g);
复制代码
有些老的问题已经被修复了。例如,下面这种流行的模式在 @babel/runtime-corejs2
不工做,可是在 @babel/runtime-corejs3
被支持。
myArrayLikeObject[Symbol.tierator] = Array.prototype[Symbol.iterator];
复制代码
尽管 @babel/runtime
早期版本不支持实例方法,可是使用一些自定义的帮助函数可以支持迭代([Symbol.iterator]()
和他的presence)。以前不支持提取 [Symbol.iterator]
方法,可是如今支持了。
做为意外收获,@babel/runtime
如今支持IE8-,可是有些限制,例如,IE8- 不支持访问器、模块转换应该用松散的方式,regenerator-runtime
(内部使用 ES5+ 实现)须要经过这个插件转译。
作了许多工做,可是 core-js
距离完美还很远。这个库和工具未来应该如何改进?语言的变化将会如何影响它?
如今,core-js
试图去支持全部可能的引擎或者咱们可以测试到的平台:甚至是IE8-,或者例如,早期版本的 Firefox。虽然它对某些用户有用,可是仅有一小部分使用 core-js
的开发者须要它。对于大多数用户,它将引发像包体积过大或者执行缓慢的问题。
主要的问题源自于支持 ES3 引擎(首先是 IE8- ):多数现代 ES 特性是基于 ES5,这些功能在老版本浏览器中均不可用。
最大的缺失特性是属性描述符:当它缺失时,一些功能不能 polyfill,由于他们要么是访问器(像 RegExp.prototype.flags
或 URL
属性的 setters )要么就是基于访问器(像 typed array polyfill)。为了解决这个不足,咱们须要使用不一样的解决方法(例如,保持 Set.prototype.size
更新)。维护这些解决方法有时很痛苦,移除他们将极大的简化许多 polyfills。
然而,描述符仅仅是问题的一部分。ES5 标准库包含了不少其余特性,他们被认为是现代 JavaScript 的基础:Object.create
,Object.getPrototypeOf
,Array.prototype.forEach
,Function.prototype.bind
,等等。和多数现代特性不一样,core-js
内部依赖他们而且为了实现一个简单的现代函数,core-js
须要加载其中一些"建筑模块"的实现。对于想要建立一个足够小的构建包和仅仅想要引入部分 core-js
的用户来讲,这是个问题。
在一些国家 IE8 仍很流行,可是为了让 web 向前发展,浏览器到了某些时候就应该消失了。 IE8
在 2009 年 3 月 19 日发布,到今天已经 10 年了。IE6 已经 18 岁了:几个月前新版的 core-js
已经再也不测试 IE6 了。
在 core-js@4
咱们应该舍弃 IE8- 和其余不知道 ES5 的引擎。
core-js
使用 CommonJS
模块规范。长期以来,他是最受欢迎的 JavaScript 模块规范,可是如今 ECMAScript 提供了他本身的模块规范。许多引擎已经支持它了。一些构建工具(像 rollup )基于它,其余的构建工具提供它做为 CommonJS
的替代。这意味提供了一个可选择的使用 ESMAScript 模块规范版本的 core-js
行得通。
core-js
当前专一在 ECMAScript 支持,可是也支持少许的跨平台以及和 ECMAScript 紧密联系的 web 标准功能。为 web 标准添加像 fetch
的这种的 polyfill 是受欢迎的功能请求。
core-js
没有增长他们的主要缘由是,他们将严重的增长构建包大小而且将强制 core-js
用户载入他们可能用不到的功能。如今 core-js
是最大限度的模块化,用户可以仅选择他们须要的功能,这就像 @babel/preset-env
和 @babel/runtime
可以帮助用户去减小没用到和没必要要的 polyfills。
如今是时候从新审视这个决定了?
@babel/runtime
目前,咱们不能像对 @babel/preset-env
那样为 @babel/runtimne
设置目标加环境。这意味即便目标是现代浏览器, @babel/runtime
也将注全部可能的 polyfills:这没必要要的增长了最终构建包的大小。
如今 core-js-compat
包函所有必要数据,未来,能够在 @babel/runtime
中添加对目标环境的编译支持,而且在 @babel/preset-env
中添加 useBuiltIns: runtime
选项。
正如上面解释的,Babel 插件给了咱们不一样的方式去优化 core-js
的使用,可是他并不完美:咱们能够改进他们。
经过 useBuiltIns: usage
选项,@babe/preset-env
可以作的比以前更好,可是针对一些不寻常的例子他们仍然会失败:当代码不能被静态分析。针对这个问题,咱们须要为库开发者寻找一个方式去肯定哪一种 polyfill 是他们的库须要的,而不是直接载入他们:某种元数据 -- 将在建立最终构建包时注入 polyfill。
另外一个针对 useBuiltIns: usage
的问题是重复的 polyfills 导入。useBuiltIns: usage
可以在每一个文件中注入许多 core-js
的导入。但若是咱们的项目有数千个文件或者即便十分之一会怎么样呢?这种状况下,与导入 core-js
自身相比,导入 core-js/...
将有更多代码行:咱们须要一种方式去收集全部的导入到一个文件中,这样才可以删除重复的。
几乎每个须要支持像 IE11
浏览器的 @babel/preset-env
用户都为每一个浏览器使用同一个构建包。这意味着彻底支持 ES2019 的现代浏览器将加载没必要要的、仅仅是 IE11 须要的 polyfills。固然,咱们能够为不一样的浏览器建立不一样的构建包来使用,例如,type=module
/ nomodules
属性:一个构建包给支持模块化的现代浏览器,另外一个给传统浏览器。不幸的是,这不是针对这个问题的完整的解决方案:基于用户代理打包目标浏览器须要的 polyfill 的服务很是有用。咱们已经有了一个 - polyfill-service
。尽管颇有趣也很流行,可是 polyfill 的质量还有不少不足。它不像几年前那么差:项目团队积极工做去改变它,可是若是你想用他们匹配原生实现,我不建议你经过这个项目使用 polyfill。许多年前我尝试经过这个项目将 core-js
做为 polyfill 的源,可是这不可能。由于 polyfill-service
依赖文件嵌套而不是模块化(就像 core-js
发布后的前几个月 😊)。
像这样一个集成了一个很棒的 polyfill 源 -- core-js
的服务,经过像 Babel 的 useBuiltIns: usage
选项,静态分析源代码真的可以引发咱们对于 polyfill 思考方式的革命。
core-js
可能的问题TC39 一直在努力工做去改进 ECMAScript:你能够经过查看 core-js
中实现全部新提案查看进度。然而,我认为有些新的提案功能在 polyfill 或者转译时可能引发严重的问题。关于这个足够能够写一篇新的文章,可是我将尝试在这总结一下个人想法。
如今,TC39 考虑给 ECMAScript 增长内置模块:一个模块化的标准库。它将成为 JavaScript 的最佳补充,而 core-js
是它能够被 polyfill 的最佳位置。根据 @babel/preset-env
和 @babel/runtime
用到的技术,理论上咱们能够经过一种简单的方式注入内置模块须要的 polyfill。然而,这个提案的当前版本会致使一些严重问题,这些问题并无使其简单明了。
内置模块的 polyfill,根据做者的提案,仅仅意味着退回到分层 API 或者 导入 maps。这代表若是原生模块缺失,它将可以经过提供的 url 载入一个polyfill。这绝对不是 polyfill 须要的,而且它与 core-js
的架构以及其余流行的 polyfill 都不兼容。导入 maps 不该该是 polyfill 内置模块的惟一方式。
咱们经过一个特定前缀使用 ES 模块语法就可以获得内置模块。这个语法在语言的早期版本并无对等的 - 转译模块不可能在如今浏览器中与未转译的交互 - 这会致使包分发的问题。
更进一步讲,他将异步工做。对于功能检测这是个严重的问题 - 当你要检测一个功能而且加载 polyfill 时脚本不会等待 - 功能检测应该同步的作。
在没有转译和 polyfill 的状况下第一次实现内置模块。若是没有修改,在当前的 core-js
格式下内置模块将不可能 polyfill。建议的 polyfill 方式将使开发变得严重复杂。
这个标准库的问题可以经过添加一个新的全局变量解决(这将是最后一个吗?):一个内置模块的注册表将容许异步的设置和获取,例如:
StandardLibraryRegistry.get(moduleName);
StandardLibraryRegistry.set(moduleName, value);
复制代码
异步回调,好比分层API应该全局注册表以后使用。
值得一提的是,它将简化将本地模块导入到老的语法的转换。
这个提案中的 新迭代器,他被很认真的重作了。装饰器定义再也不是语法糖,就像内置模块,咱们不能在老版本的语言中编写装饰器并将其用做原生装饰器。除此以外,装饰器不只仅是普通的标识符 - 他们生活在平行的词汇范围内:这意味着已经编译的装饰器不能喝原生装饰器交互。
提案做者建议使用未编译的装饰器发布包,让包的使用者选择去编译他们的依赖。然而,在不一样的状况下是不可能的。当他们被添加到 JS 标准库时,这个方法将阻止 core-js
polyfill 新的内置装饰器。
装饰器应该是在某些东西上应用功能的一种方法,他们应该仅仅是包裹的语法糖。为何要复杂化呢?
若是引入的一个语言功能不是从根本上是新的,在语言的早期版本什么不该该实现是能够选择的,咱们可以转译或者 polyfill 它,被转译或者 polyfill 的代码应该可以和支持这个功能的浏览器原生交互。
我但愿根据提案做者和委员会的智慧,这些提案可以被采纳,这样才可以合理的转译或者 polyfill 他们。
若是你对 core-js
项目感兴趣,或者你在你平常工做中使用它,你能够成为 OpenCollective 或者 Patreon 捐赠者。core-js
的背后不是一个公司:他的未来要靠你。
这里 能够评论这篇文章。
Denis Pushkarev,2019年3月19日,感谢 Nicolò Ribaudo 编辑。
感谢你阅读到这里,翻译的很差的地方,还请指点。但愿个人内容能让你受用,再次感谢。by llccing 千里