Github.com/zloirock/co… The original link

After a year and a half in development, dozens of versions, and many sleepless nights, core-js@3 is finally released. This is one of the biggest changes to core-JS and Babel patch related functionality.

What is the core – js?

  • It’s polyfill of the JavaScript standard library, and it supports
    • The latest ECMAScript standard
    • ECMAScript standard library proposal
    • Some WHATGW/W3C standards (cross-platform or ECMAScript related)
  • It’s as modular as possible: you can load only the features you want to use
  • It does not pollute the global namespace
  • itTightly integrated with Babel: This can be optimizedcore-jsThe import of

It’s the most common and popular way to patch the JavaScript standard library, but a large percentage of developers don’t know they’re indirectly using core-js🙂

contribution

Core-js is my own hobby project, which has not brought me any profit. It took me a long time and was really expensive: I had left my job a few months ago in order to finish core-js@3. The program has been a catalyst for many people and companies. Because of this, it makes sense to raise money to support core-JS maintenance.

If you’re interested in core-JS or use it in your everyday work, you can become a patron at Open Collective or On Patreon.

You can offer me a good job related to what I’m doing.

Or you can contribute in another way, by helping to improve the code, testing, or documentation (core-JS documentation is still terrible!). .

core-js@3What has changed?

Changing content in the JavaScript standard library

This release contains rich, new JavaScript patches for two reasons:

  • core-jsBreak changes are only made when the major version is updated, even if it needs to be aligned with the content of the proposal.
  • core-js@2It went into a functional freeze a year and a half ago; All new features can only be added tocore-js@3This branch.

Stable ECMAScript functionality

In addition to stable ECMAScript functionality that has been almost fully supported in Core-JS for quite some time, core-js@3 introduces some new features:

  • Added support for the two well-known tags @@isconcatSpreadable and @@Species introduced in ECMAScript 2015 to all methods that use them.
  • Added from ECMAScript 2018Array.prototype.flat 和 Array.prototype.flatMap(core-js@2forArray.prototype.flattenPatches are available for this older version of the proposal).
  • Added the Object.fromEntries method from ECMAScript 2019
  • Increase from ECMAScript 2019 Symbol. The prototype. The description accessors

Some features that were accepted as proposals in ES2016-ES2019 and have been in use for a long time are now marked as stable:

  • Array. The prototype. Includes and TypedArray. Prototype. Includes method (ESMAScript 2016)
  • Object.values and Object.entries methods (ECMAScript 2017)
  • Object. GetOwnPropertyDescriptors method (ECMAScript 2017).
  • String. The prototype. PadStart and String. Prototype. PadEnd method (ECMAScript 2017).
  • Promise. Prototype. Finally method (ECMAScript 2018)
  • Symbol. AsyncIterator well-known flag (ECMAScript 2018)
  • Object. The prototype. __define (Getter | Setter) __ and Object. The prototype. __lookup (Getter | Setter) __ method (ECMAScript 2018).
  • String. The prototype. Trim (Start | | End Left | Right) method (ECMAScript 2019).

Fixed a number of issues for browsers, for example, the Safari 12.0 array.prototype. reverse bug has been fixed.

ECMAScript proposal

In addition to the support mentioned above, core-js@3 now supports the following ECMAScript proposals:

  • globalThisStage 3 (and now Stage 4) proposals — before, there wereglobal 和 System.global
  • Promise. AllSettled Stage 2 (now Stage 4) proposal
  • newSetmethodsStage 2 Proposal:
    • Set.prototype.difference
    • Set.prototype.intersection
    • Set.prototype.isDisjoinFrom
    • Set.prototype.isSubsetOf
    • Set.prototype.isSupersetOf
    • Set.prototype.symmetricDifference
    • Set.prototype.union
  • A new method of collectionsThe Stage 1 proposal includes many new and useful approaches:
    • Map.groupBy
    • Map.keyBy
    • Map.prototype.deleteAll
    • Map.prototype.every
    • Map.prototype.filter
    • Map.prototype.find
    • Map.prototype.findKey
    • Map.prototype.includes
    • Map.prototype.keyOf
    • Map.prototype.mapKeys
    • Map.prototype.mapValues
    • Map.prototype.merge
    • Map.prototype.reduce
    • Map.prototype.some
    • Map.prototype.update
    • Set.prototype.addAll
    • Set.prototype.deleteAll
    • Set.prototype.every
    • Set.prototype.filter
    • Set.prototype.find
    • Set.prototype.join
    • Set.prototype.map
    • Set.prototype.reduce
    • Set.prototype.some
    • WeakMap.prototype.deleteAll
    • WeakSet.prototype.addAll
    • WeakSet.prototype.deleteAll
  • String. The prototype. The replaceAll stage 1 (now the stage 3) proposal
  • String. The prototype. CodePoints stage 1 proposal
  • Array. The prototype. The last (Item | Index) stage 1 proposal
  • The compositeKey and compositeSymbol methods stage 1 proposal
  • Number.fromstring Stage 1 proposal
  • Math. SeededPRNG Stage 1 proposal
  • Promise.any (merge error) Stage 0 (now Stage 3) proposal

Some of the proposals have changed a lot, and Core-JS will be updated accordingly:

  • String. The prototype. MatchAll stage 3 proposal
  • Observable Stage 1 proposal

Web standards

Many useful features have been added to this category.

The most important ones are urls and URLSearchParams. It is one of the most popular feature requests. Adding urls and URLSearchParams, ensuring maximum compliance with the specification, and keeping the source code compact enough to support any environment is one of the most difficult tasks in core-js@3 development.

The core-js@3 package provides a standard method for creating microtasks in JavaScript: queueMicrotask. core-js@2 provides the ASAP function, which provides the same functionality as the older proposal. QueueMicrotask is defined in the HTML standard and is already available in modern browsers such as Chromium or NodeJS.

Another popular feature request is the.foreach method that supports DOM collections. Since core-js already polyfills the DOM collection iterator, why not add.foreach to the node list and DOMTokenList as well?

Remove outdated features:

  • Reflect.enumrateBecause it has been removed from the criteria
  • System.global 和 globalNow they have beenglobalThisInstead of
  • Array.prototype.flattenHas now beenArray.prototype.flatInstead of
  • asap 被 queueMicrotaskInstead of
  • Error.isErrorIt’s been revoked a long time
  • RegExp.escapeIt was rejected a long time ago
  • Map.prototype.toJSON 和 Set.prototype.toJSONIt was rejected a long time ago
  • Unnecessary and erroneously added iterator methods:CSSRuleList.MediaList.StyleSheetList.

No more non-standard, non-proposal features

Many years ago, I started writing a library that was the heart of my JavaScript programs: the library wrapped polyfills and some of the utility functions I needed. Some time later, the library was released under the name core-js. I think most core-JS users now don’t need non-standard core-JS features, most of them were removed in earlier versions, and it’s time to remove the rest from Core-JS. From this version on, core-JS can be called polyfill.

Package, entry, and module name

One issue mentioned a large core-js package (~2MB) with many duplicate files. For this reason, Core-JS is split into three packages:

  • Core-js defines polyfills globally. (~500KB, compressed and gzipped 40KB)
  • core-js-pureProvides polyfills that do not pollute global variables. It andcore-js@2In thecore-js/libraryQuite. (~ 440 KB)
  • Core-js-bundle: A packaged version that defines the global population

In earlier versions of Core-JS, stable ECMAScript functionality and polyfill modularity of ECMAScript proposals required es6, respectively. And es7. Prefix. This decision was made in 2014, when all features after ES6 were treated as ES7. Es is added to all stable ECMAScript features in core-js@3. Prefix, ECMAScript proposal adds the esnext. Prefix.

Almost all CommonJS entries have changed. core-js@3 has more entry points than core-js@2: this gives you maximum flexibility and allows you to introduce only the dependencies your application needs.

Here are some examples of how to use the new entry:

// Use 'core-js' to patch all functions:
import "core-js";
// Using only stable 'core-js' functionality -es and web standards:
import "core-js/stable";
// Use only the stable ES function
import "core-js/es";

// If you want to use the 'Set' patch
// All 'Set' -es proposals, related functions:
import "core-js/features/set";
// Stable 'Set' ES functionality and functionality from web standards
// (DOM set iterator)
import "core-js/stable/set";
// Only the stable ES function required by 'Set'
import "core-js/es/set";
// Same as above, but does not pollute the global namespace
import Set from "core-js-pure/features/set";
import Set from "core-js-pure/stable/set";
import Set from "core-js-pure/es/set";


// Patch only the required methods
import "core-js/feature/set/intersection";
import "core-js/stable/queque-microtask";
import "core-js/es/array/from";

// Patch the Reflect Metadata proposal
import "core-js/proposals/reflect-metadata";
// Patch all stage 2+ proposals
import "core-js/stage/2";
Copy the code

Other important changes

Core-js Polyfill is able to configure the level of intrusion. You can modify the default behavior of Core-JS if you think there are situations in which core-JS functionality detection is too intrusive, the native implementation is sufficient for you, or a faulty implementation is not detected by Core-JS.

Core-js adds a.sham attribute if every detail of the specification cannot be installed to implement a function, for example, symbol.sham is true in IE11.

There will be no LiveScript! When I started core-JS, I mostly used LiveScript; After a while, I rewrote all polyfills in JavaScript. The tool functions for testing and helping in core-js@2 still use LiveScript: it’s a very interesting coffeescript-like language with powerful syntactic sugar that allows you to write very compact code, but it’s almost dead. In addition, it also contributes to the barrier of Core-JS, since most core-JS users don’t know the language. core-js@3 tests and utility functions use modern ES syntax: it would be a good time to contribute to core-JS 🙂.

For most users, TO optimize core-JS imports, I recommend using Babel. Of course, there are situations where Core-Js-Builder is still useful. It now supports the target argument, using a browser list query with the target engine – you can create a bundle that contains only the polyfills that the target engine needs. For this case, I did core-js-compat, which you can learn more about from the @babel/preset-env section of this article.


This is just the tip of the iceberg, more changes are happening inside. More information about core-JS changes can be found in Changelog.

Babel

As mentioned above, Babel and Core-JS are tightly integrated: Babel offers the possibility of optimizing core-JS optimized imports. An important part of the development at core-js@3 is improving core-JS related Babel functionality (see this PR). These changes were released in Babel 7.4.0.

babel/polyfill

@babel/polyfill is a wrapped package containing only the introduction of core-JS stable (also included in Babel 6) and regenerator-Runtime/Runtime to translate generators and async functions. This package does not provide a smooth upgrade path from core-js@2 to core-js@3: for this reason, it was decided to scrap @babel/ Polyfill and instead introduce the required Core-JS and Regenerator-Runtime, respectively.

The original

import "@babel/polyfill";
Copy the code

Now use two lines instead:

import "core-js/stable";
import "regenerator-runtime/runtime";
Copy the code

Don’t forget to install both dependencies directly!

npm i --save core-js regenerator-runtime
Copy the code

@babe/preset-env

There are two different modes for @babel/preset-env, optimizing core-js import with useBuiltIns options: Entry and Usage.

Babel 7.4.0 introduces common changes for both modes, as well as specific modifications for each mode.

Since @babel/preset-env now supports core-js@2 and core-js@3, useBuiltIns requires a new option — corejs, which is used to define the version that uses Corejs (corejs: 2 or Corejs: 3). If this is not set, corejs: 2 is the default and will be warned.

To enable Babel to support new core-JS features that will be introduced in future minor releases, you can define explicit minor release numbers in your project. For example, if you want to use the new features of this release using [email protected], you can set the corejs option to 3.1: corejs: ‘3.1’ or corejs: {version: ‘3.1’}.

One of the most important features of @babel/ PRESET -env is to provide a data source for different browser-supported features to determine whether core-js is needed to populate something. Caniuse, MDN, and Compat-table are great educational resources, but that doesn’t mean they can be used as data sources by developers: Only the COMPat-table package contains good ES related datasets, which are used by @babel/preset-env, but there are some limitations:

  • It contains data only about ECMAScript features and proposals, and has nothing to do with Web platform features such as setImmediate or DOM set iterators. So even now, @babel/preset-env still adds all web platform features via core-js even if they are already supported.

  • It doesn’t contain any browser (even serious) bug information: for example, Array#reverse in Safari 12 mentioned above, but compat-table doesn’t mark it as unsupported. On the other hand, Core-JS has fixed this bad implementation, but cannot use it because of compat-table relationships.

  • It only provides basic, naive tests, and does not check whether the functionality works in a real-world environment. For example, older versions of Safari’s broken iterators don’t have.next methods, but compat-table shows Safari does because it uses typeof methods to detect that iterator methods return “function”. Some features like typed Arrays have little coverage.

  • Compat-tables are not designed to provide data to tools. I am one of the maintainers of Compat-table, but other maintainers object to maintaining this feature.

For this reason, I created core-js-compat: it provides necessary data for core-JS modules in different browsers. When using core-js@3, @babel/preset-env replaces compat-table with a new package. Please help us test and provide mapping of missing engine data! 😊.

Prior to Babel 7.3, @babel/preset-env had some issues related to polyfills injection order. Starting in 7.4.0, @babel/preset-env only adds needed polyfills in the recommended order.

useBuiltIns: entry with corejs: 3

When used with this option, @babel/preset-env instead of referring directly to core-js introduces modules specific to the target environment.

Before this change, @babel/preset only replaces import ‘@babel/polyfill’ and import ‘core-js’, which are synonyms used to polyfill all stable JavaScript features.

@babel/polyfill is now deprecated, @babel/preset-env will not be preset when corejs is set to 3.

The equivalent substitution @babel/polyfill in core-js@3 is

import "core-js/stable";
import "regenerator-runtime/runtime";
Copy the code

The above content will be converted to @babel/preset-env when the target browser is Chrome 72

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";
Copy the code

When the target browser is Chrome 73 (which fully supports the ES2019 library), it will become less introduced:

import "core-js/modules/web.immediate";
Copy the code

Since @babel/polyfill was deprecated in favor of separate Core-JS and Regenerator-Runtime, we were able to optimize the import of Regenerator-Runtime. For this reason, if the target browser natively supports generators, the regenerator-Runtime import will be removed from the source code.

Now, set @babel/preset-env to useBuiltIns: Entry mode to compile all available core-JS entries and their combinations. This means you can customize it by using different core-JS entries, which will be optimized for the target environment.

For example, the target environment is Chrome 72,

import "core-js/es";
import "core-js/proposals/set-methods";
import "core-js/features/set/map";
Copy the code

Will be replaced by

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";
Copy the code

useBuiltIns: usage with corejs: 3

When used with this option, @babel/preset-env introduces polyfills at the beginning of each file that are not supported by the target environment and are only used in the current file.

For example,

const set = new Set([1.2.3]);
[1.2.3].includes(2);
Copy the code

When the target environment is an older browser such as IE 11, will be converted to

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);
Copy the code

No import is required when the target is Chrome 72 because the environment needs polyfills:

const set = new Set([1.2.3]);
[1.2.3].includes(2);
Copy the code

Before Babel 7.3, useBuiltIns: usage was unstable and not reliable enough: many polyfills did not wrap and added many polyfills that were not necessarily dependent. In Babel 7.4, I tried to make it understand every possible usage pattern.

In terms of property accessors, object destructions, in operators, and global object attribute access, I improved the technique for determining which polyfills to use.

@babel/preset-env now injects polyfills needed for syntax features: iterators when using for-of, deconstruction, extension operators and yield delegates; Promises with dynamic import, asynchronous functions, generators, etc.

Babel 7.4 supports injection proposal polyfills. By default, @babel/preset-env will not inject them, but you can set them through the proposals flag: corejs: {version: 3, even though: true}.

@babel/runtime

When using core-js@3, @babel/ transform-Runtime now infuses polyfills via core-js-pure (a version of core-js that does not pollute global variables).

core-js@3 and @babel/ Runtime have been integrated by setting the @babel/ transform-Runtime corejs: 3 option and creating the @babel/ Runtime-corejs3 package. But what good will it do?

A popular issue of @babel/ Runtime is that instance methods are not supported. Starting with @babel/runtime-corejs3, this issue has been resolved. For example,

array.includes(something);
Copy the code

Will be compiled to

import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";

_includesInstanceProperty(array).call(array, something);
Copy the code

Another notable change is support for the ECMAScript proposal. By default, @babel/ plugin-transform-Runtime does not inject polyfills for proposals and uses entries that do not contain proposals. But just as you did in @babel/preset-env, you can set the proposals flag to enable: corejs: {version: 3, proposed: true}.

There is no sign of proposals,

new Set([1.2.3.2.1]);
string.matchAll(/something/g);
Copy the code

Will compile to:

import _Set from "@babel/runtime-corejs/core-js-stable/set";

new _set([1.2.3.2.1]);
string.matchAll(/something/g);
Copy the code

When the proposals are set, they will be:

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);
Copy the code

Some of the old problems have been fixed. For example, the following popular pattern does not work at @babel/runtime-corejs2, but is supported at @babel/runtime-corejs3.

myArrayLikeObject[Symbol.tierator] = Array.prototype[Symbol.iterator];
Copy the code

Although earlier versions of @babel/ Runtime did not support instance methods, iterating ([symbol.iterator]() and its presence) was possible using some custom helper functions. The extract [symbol.iterator] method was not previously supported, but is now supported.

As a bonus, @babel/ Runtime now supports IE8-, but with some limitations, for example, IE8- does not support accessors, module transformations should be done in a loose manner, and Regenerator-Runtime (implemented internally using ES5+) needs to be translated via this plug-in.

Swimming in the future

A lot of work has been done, but Core-JS is far from perfect. How should the library and tools be improved in the future? How will the language change affect it?

Older engine support

Now, Core-JS tries to support every possible engine or platform we can test on: even IE8-, or, for example, earlier versions of Firefox. While it is useful for some users, only a small percentage of core-JS developers need it. For most users, it will cause problems such as bulky packages or slow execution.

The main problem stems from support for the ES3 engine (IE8- first) : most modern ES features are based on ES5 and are not available in older browsers.

The biggest missing feature is the attribute descriptor: When it is missing, some functions cannot polyfill because they are either accessors (like RegExp. Prototype. flags or SETters for URL attributes) or are accessor-based (like typed array polyfill). To address this deficiency, we need to use a different workaround (for example, keep set.prototype.size updated). Maintaining these solutions can be painful, and removing them will greatly simplify many polyfills.

However, descriptors are only part of the problem. The ES5 library contains many other features that are considered the foundation of modern JavaScript: Object.create, Object.getProtoTypeof, array.prototype. forEach, function.prototype. bind, etc. Unlike most modern features, core-JS relies on them internally and in order to implement a simple modern function, core-JS needs to load implementations of some of these “building blocks”. This is a problem for users who want to create a small enough build pack and just want to introduce parts of Core-JS.

IE8 is still popular in some countries, but in order for the Web to move forward, browsers need to go away at some point. IE8 was released on March 19, 2009, and it has been 10 years since then. IE6 is 18 years old: the new version of Core-JS stopped testing IE6 a few months ago.

At core-js@4 we should ditch IE8- and other engines that don’t know ES5.

ECMAScript module

Core-js uses the CommonJS module specification. It has long been the most popular JavaScript module specification, but now ECMAScript offers its own module specification. Many engines already support it. Some build tools (like Rollup) are based on it, and others provide it as an alternative to CommonJS. This means that it makes sense to provide an alternative version of core-JS that uses the ESMAScript module specification.

Support web standards extensions?

Core-js currently focuses on ECMAScript support, but also supports a small number of cross-platform and ecMAScript-tied Web standards features. Adding polyfills like Fetch’s for Web standards is a welcome feature request.

The main reason core-JS doesn’t add them is that they will significantly increase the build package size and force core-JS users to load features they may not need. Core-js is now as modular as possible and the user can choose only the features they want, just as @babel/preset-env and @babel/ Runtime help the user to reduce useless and unnecessary polyfills.

Is it time to revisit that decision?

Specific to the target environment@babel/runtime

For now, we can’t set a target plus environment for @babel/runtimne like we can for @babel/preset-env. This means that even if the target is a modern browser, @babel/ Runtime will fill all possible polyfills: this unnecessarily increases the size of the final build package.

Now that the core-js-compat package has all the necessary data, in the future, build support for the target environment can be added in @babel/ Runtime and useBuiltIns: Runtime option can be added in @babel/preset-env.

Better optimization of polyfill loading

As explained above, the Babel plugin gives us different ways to optimize the use of Core-JS, but it’s not perfect: we can improve them.

@babe/preset-env can do better with useBuiltIns: Usage option, but they still fail for some unusual cases: when the code can’t be statically analyzed. To address this problem, we need to find a way for library developers to determine which polyfills their library needs, rather than loading them directly: some kind of metadata that will be injected into polyfills when the final build package is created.

Another problem with useBuiltIns: Usage is the duplicate polyfills import. UseBuiltIns: Usage is able to inject many core-JS imports into each file. But what if our project had thousands of files or even a tenth of them? In this case, importing core-js/… There will be more lines of code: we need a way to collect all the imports into one file so that duplicate ones can be removed.

Almost every @babel/ Preset -env user who needs to support browsers like IE11 uses the same build pack for each browser. This means that modern browsers that fully support ES2019 will load unnecessary polyfills that are only required by IE11. Of course, we can create different build packages for different browsers to use, for example, the Type =module/nomodules property: one build package for modern browsers that support modularity, and another for traditional browsers. Unfortunately, this is not a complete solution to this problem: a service based on the user agent that packages polyfill required by the target browser is very useful. We already have a -polyfill-service. Although fun and popular, Polyfill’s quality leaves a lot to be desired. It’s not as bad as it was a few years ago: the project team worked actively to change it, but IF you want to match them with the native implementation, I don’t recommend using Polyfill through this project. Many years ago I tried using core-JS as a source for polyfill through this project, but it wasn’t possible. Because polyfill-service relies on file nesting rather than modularity (as in the first few months after core-JS was released 😊).

A service like this that integrates a great polyfill source, core-js, with options like Babel’s useBuiltIns: Usage, statically analyzing source code can really revolutionize the way we think about polyfill.

New features from TC39 preplans andcore-jsPossible problems

TC39 has been working hard to improve ECMAScript: you can see the progress of all new proposals implemented in Core-JS. However, I think some of the new proposal features can cause serious problems when polyfilling or translating. This is enough to write a new article about, but I’ll try to summarize my thoughts here.

Standard library proposal, Stage 1

TC39 is now considering adding a built-in module to ECMAScript: a modular standard library. It will be the best complement to JavaScript, and core-js is the best place where it can be polyfilled. Based on the techniques used by @babel/preset-env and @babel/ Runtime, it is theoretically possible to inject polyfills needed by built-in modules in a simple way. However, the current version of the proposal causes serious problems that do not make it straightforward.

Polyfill of built-in modules, according to the authors’ proposal, simply means falling back to a layered API or importing maps. This indicates that if the native module is missing, it will be able to load a Polyfill via the url provided. This is definitely not what Polyfill needs, and it is incompatible with core-JS architecture and other popular Polyfills. Importing maps shouldn’t be the only way polyfill’s built-in module works.

We can get built-in modules by using ES module syntax with a specific prefix. This syntax did not have an equivalent in earlier versions of the language – translated modules would not be able to interact with untranslated modules in current browsers – which could lead to package distribution problems.

Furthermore, he will work asynchronously. This is a serious problem for feature checking – when you are checking a feature and the script does not wait while loading polyfill – feature checking should be done synchronously.

Implement the built-in module for the first time without translation and polyfill. Without modification, it will be impossible to polyfill built-in modules in the current core-JS format. The proposed polyfill approach would seriously complicate development.

This library problem can be solved by adding a new global variable (will this be the last one?). A built-in module registry will allow asynchronous setup and retrieval, for example:

StandardLibraryRegistry.get(moduleName);
StandardLibraryRegistry.set(moduleName, value);
Copy the code

Asynchronous callbacks, such as hierarchical apis, should be used after the global registry.

Notably, it will simplify the conversion of importing native modules into the old syntax.

Decorator proposal, new iterator syntax, Stage 2

The new iterator in this proposal has been carefully reworked. Decorator definitions are no longer syntactic sugar, just like built-in modules, we can’t write decorators in older languages and use them as native decorators. In addition, decorators are not just plain identifiers – they live in a parallel vocabulary: this means that already compiled decorators cannot interact with native decorators.

The proposal authors suggest publishing packages with uncompiled decorators and giving package users the option to compile their dependencies. However, it is not possible under different circumstances. This method will block core-JS polyfill from new built-in decorators when they are added to the JS standard library.

Decorators should be a way to apply functionality to something; they should just be wrapped syntax sugar. Why complicate it?


If an introduced language feature is not fundamentally new and there is a choice as to what should not be implemented in earlier versions of the language, we can translate or polyfill it, and the translated or polyfill code should be able to interact natively with browsers that support this feature.

I hope that based on the wisdom of the proposer and the committee, these proposals can be adopted so that they can be properly translated or polyfilled.


If you’re interested in the Core-JS project, or if you use it in your daily work, you can become an OpenCollective or Patreon donor. Core-js is not a company: its future depends on you.


You can comment on this article here.

Denis Pushkarev, 19 March 2019, thanks to Editor Nicolo Ribaudo.

Materials that may be used

  • CommonJS module specification
  • ECMAScript module specification

Thank you for reading

Thank you for reading here, the translation of the bad place, please also give advice. I hope you can enjoy my content. Thank you again. By llccing li