1 overview
Babel itself is a compiler, but the focus of this article is on the subtitle of the website, how to use Babel to help you use the latest version of JS when the current runtime (such as the browser) does not implement the relevant specifications (including ES262 and Web Standard). It is suggested that the two articles be read together.
To do this, Babel needs to do two things
- The syntax of the new JS is implemented with the old syntax, so that it can be run at the corresponding runtime, such as the arrow function
- Patches (also known as polyfills) in older runtimes to use functionality defined in new versions of JS but provided in older runtimes fall into three categories
- Newly defined built-in objects, such as
Promise
- Static methods added to existing built-in objects, such as
Array.from
- New instance methods added to existing built-in objects, such as
Array.prototype.includes
- Newly defined built-in objects, such as
For the first feature, Babel can convert various new grammars with plug-ins. How to develop plug-ins and how to convert them can also be found in the article above.
For the second function, Babel relies on core-JS, developed by someone who has been looking for a job for years.
The completion of the above two functions will be introduced in detail below. In the first part, the main content of Babel will be discussed. In the second part, core-JS and its combination with Babel will be introduced.
Babel and syntax conversion
The following steps are required to convert the syntax using Babel
- Install various packages first
- Babel core package @babel/core
- Install @babel/ CLI for command line calls
- Install plug-ins needed for syntax transformation
- Specify plug-ins and other options to use during the transformation, using the configuration
After completing the above steps, run cli commands or related scripts to convert Babel.
2.1 Packages Involved
2.1.1 @ Babel/core
Babel itself, which returns nothing without a plug-in, or else operates on the source code according to the relevant plug-in.
2.1.2 @ Babel/cli
Provides a way to execute Babel from the command line. See the API here
2.1.3 Related plug-ins
Plug-ins are used to guide related syntax parsing and AST processing. The former are called Syntax Plugins and the latter Transform Plugins
Syntax Plugins are generally not operated directly and are automatically enabled when the corresponding Transform Plugins are used
Transform Plugins contain the following categories
- All versions of ES
- Modules
- Experimental grammar
- To achieve compression
- react
- Others, such as typescript and runtime, are covered later
In order to make it easier to use various plug-ins, Babel combines various plug-ins. These combinations are called Presets, and they share the same configuration
- @babel/preset-env contains all new syntax plug-ins needed for the target environment and is the most commonly used preset, the configuration of which is described in the next chapter in conjunction with Core-JS
- @ Babel/preset – flow to flow
- @ Babel/preset – react to react
- @ Babel/preset – typescript for ts
You can also customize presets
2.2 configuration
2.2.1 Classification of configuration files
Babel accepts a variety of configuration files, including
- babel.config.json
- .babelrc.json
- package.json
Alternatively, it can be specified when the CLI or API is used. Plugin and Preset are mainly specified. For details, see here
2.2.2 Specifying a path
The following forms can be used when a plugin or preset is specified
- If the plugin is downloaded by NPM, you can pass the plugin name directly, and Babel will go to node_modules
babel-plugin-
Part (Use preset omitted isbabel-preset-
), such as
{"plugins": [" myplugins ", "babel-plugin-myplugins" // equivalent]} // or {"plugins": [" myplugins ", "babel-plugin-myplugins" // equivalent]} // or {"plugins": [ "@org/babel-plugin-name", "@org/name" // equivalent ] }Copy the code
- You can also specify a relative/absolute path for the plug-in
{
"plugins": ["./node_modules/asdf/plugin"]
}
Copy the code
2.2.3 order
The sequence of plugin or preset affects the execution order of the plug-in visitor, which follows the following rule
- Plugin takes precedence over preset
- Plugin from front to back
- Preset is from back to front
3 polyfill and core – js
Refer to the core-JS official for this section
3.1 polyfill
When it comes to polyfill, a lot of people think of @babel/polyfill, but it’s out of date. It was abandoned for two reasons, according to the archaeological data in the previous link
- This package simply introduces stable core-js and regenerator-Runtime /runtime, the latter of which can be replaced by the @babel/plugin-transform-regenerator
- This package does not smoothly transition from core-js@2 to core-js@3
So let’s look at core-JS in detail
3.2 the core – js
3.2.1 What is Core-JS
Core-js can be understood in four ways
- Polyfill is a JS standard library supported by Polyfill
- The latest ES standard
- Es standard proposal
- web standard
- Maximum modularity, you can only introduce what you need
- Can be used without polluting the full name namespace
- Integrated with Babel, made a lot of optimizations
The most recent and recommended version of Core-JS is core-js@3, which is divided into three packages
- Core-js defines a global polyfill
- Core-js-pure does not pollute versions of global variables; instance methods are mainly implemented only in version 3
- Core-js-bundle core-js is a separate file, which we will not consider in this article because we usually deal with it in a modular way. See the difference between core-js and core-js
3.2.2 How to use Core-js alone: CommonJS API
Core-js can be used either alone or in combination with Babel. Here’s how to use it alone, and see the next chapter for how to use it with Babel.
The usage in this case is to use import directly to introduce the relevant module as needed before any other code within the module
- modules path
The node_modules folder is divided into subdirectories that can be imported
- Es contains features of Stable ECMAScript Features
- Features includes all core-js Features is a recommendation introduced on demand
- The proposals contain the proposal features
- Stable includes all Stable core-JS features and is an on-demand recommendation
- The stage contains features of ECMAScript proposals
- The Web contains WHATWG/W3C features
You can also directly import concrete subfiles such as concrete objects or methods
import 'core-js/features/array/from'; // <- at the top of your entry point import 'core-js/features/array/flat'; // <- at the top of your entry point import 'core-js/features/set'; // <- at the top of your entry point import 'core-js/features/promise'; // <- at the top of your entry point Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] [1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5] Promise.resolve(32).then(x => console.log(x)); / / = > 32Copy the code
If the directories are not included, they include the features of es, Proposals, and Web subdirectories, for example
import 'core-js'; // <- at the top of your entry point Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] [1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5] Promise.resolve(32).then(x => console.log(x)); / / = > 32Copy the code
- Do not pollute global variables
As mentioned above, core-js-pure is the version that does not pollute global variables. Static methods and static methods can be used directly. If the current environment contains this feature, such as Set, it will be overwritten by introduced modules, you can consider using an alias.
import from from 'core-js-pure/features/array/from'; import flat from 'core-js-pure/features/array/flat'; import Set from 'core-js-pure/features/set'; import Promise from 'core-js-pure/features/promise'; from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] flat([1, [2, 3], [4, [5]]], 2); // => [1, 2, 3, 4, 5] Promise.resolve(32).then(x => console.log(x)); / / = > 32Copy the code
When working with instance methods, prototype methods cannot be directly converted to static methods as in other scenarios, which are implemented in core-js@3 using the binding operator (that is ::) plus further compilation. Methods in the /virtual/ directory should be introduced
import fill from 'core-js-pure/features/array/virtual/fill'; import findIndex from 'core-js-pure/features/array/virtual/find-index'; Array(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && ! (it % 8)); // => 4 // or import { fill, findIndex } from 'core-js-pure/features/array/virtual'; Array(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && ! (it % 8)); / / = > 4Copy the code
4 use Babel in combination with core-js
Core-js can be simplified using plug-ins in Babel. Note do not configure core-js at the same time. Otherwise, conflicts may occur.
4.1 @ Babel/preset – env
The useBuiltIns option indicates the use of the global version of Core-JS, which is represented by the corejs parameter, and can add proposals: True to implement the features in the proposal
Corejs: {version: '3.8', proposals: true}Copy the code
Also don’t forget to install the core-JS package for the global version
npm install core-js@3 --save
Copy the code
Refer to the official documentation for more usage of preset-env
4.2 @ Babel/runtime and @ Babel/plugin – transform – runtime
Can be used with the Pure version of core-js to simplify usage of core-js-pure by directly using instance methods and so on without contaminating global variables. The configuration is the same as that in PRESET -env, runtime should be downloaded according to corejs configuration (for example, corejs3 corresponds to @babel/ Runtime-corejs3). Note that only version 3 provides instance methods.
@ Babel/plugin – transform – runtime will
var sym = Symbol(); var promise = Promise.resolve(); var check = arr.includes("yeah!" ); console.log(arr[Symbol.iterator]());Copy the code
into
import _getIterator from "@babel/runtime-corejs3/core-js/get-iterator"; import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; import _Promise from "@babel/runtime-corejs3/core-js-stable/promise"; import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol"; var sym = _Symbol(); var promise = _Promise.resolve(); var check = _includesInstanceProperty(arr).call(arr, "yeah!" ); console.log(_getIterator(arr));Copy the code
Refer to official documentation for more features and technical details
5 Core-JS does not include polyfill
- The polyfill associated with String#normalize is large, use a separate package unorm if necessary, as well as ecma-402 Intl
- Proxy cannot polyfill, proxy-Polyfill provides some functionality
- Window. fetch is not implemented because it is not a cross-platform feature.
End and spend