This article focuses on the basic usage of Babel 7 and its new features in the configuration of monorepos type projects. The Clone example source code is available here, and simple examples are available using the online compilation platform provided by Babel.

start

Babel is a JavaScript compiler. It is primarily used to convert ECMAScript 2015+ code into syntax that can run in current or older versions of browsers or other environments.

Syntax conversion; Polyfill to add missing features to the target environment (via third-party Polyfill modules, such as core-js); Source code conversion (Codemods).

The website mentions a few things Babel will do for you 👆, because in addition to the new syntax, ECMAScript 2015+ code also includes some new features: Built-in objects (such as Promise), new static properties (such as array.from), and instance properties (such as [].includes). The syntax can be converted to ES5 syntax by plug-ins for older browser compatibility, while new features are implemented by injecting Polyfill, Polyfill adds features to global scopes, native objects (such as Array), or their prototypes (such as array.prototype), which also pollute the global environment. Babel uses core-JS to provide polyfills.

@babel/polyfillDeprecated at first, deprecated at Babel 7.4.0

@babel/ Polyfill is a library that Babel provides as a separate library from Polyfill. It contains core-js and a custom ReGenerator Runtime to simulate a complete ES2015+ environment. Previously, the library itself was equivalent to:

import "core-js/shim";  // Stage proposal containing < Stage 4
import "regenerator-runtime/runtime"; // Generator functions
Copy the code

Using @babel/polyfill can inject all polyfills, which is too much for one library/tool, or you don’t have complete control over the environment in which your code is running, contaminating the whole world can cause some problems. So it only works with applications or command-line tools. Now @babel/ Polyfill itself uses polyfill with the standard ECMAScript feature in Core-JS V2, namely:

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

If you need to populate a feature in the proposal Stage (< Stage 4), install Core-JS v2+ and import the corresponding polyfill from it, such as:

// for core-js v2:
import "core-js/fn/array/flat-map";
// for core-js v3:
import "core-js/features/array/flat-map";
Copy the code

Core-js V3 is also fully modular, core-JS can introduce a polyfill individually as needed, and @babel/ PRESET -env can introduce the needed polyfill intelligently according to the target environment. So @babel/ Polyfill is no longer valuable.

Common commands

npm install @babel/cli @babel/core --save-dev
Copy the code
  • @babel/cli: a built-in CLI tool that compiles files using the CLI.
  • @babel/core: Babel core function module. It includes parsing, transforming, and generating correlationAPI.

Common commands:

npx babel example.js
# specify the output file and start listening mode
npx babel example.js --out-file compiled.js --watch
# shorthand
npx babel example.js -o compiled.js -w

Compile directory
npx babel src --out-dir lib
# shorthand
npx babel src -d lib
Copy the code

See more Babel commands here.

NPX Babel must be installed before it can be executed@babel/cli 和 @babel/core, otherwise NPX will install old onesbabel 6.xVersion.

If you don’t want to have to type NPX and such a long command every time, you can write the command to NPM and run the script. NPM run build compiles all files in the SRC directory:

{
  "scripts": {
    "build": "babel src --out-dir lib --watch"
  }
}
Copy the code

Unlike webPack and rollup, Babel is file-to-file compilation without specifying a starting point for an entry file.

The configuration file

Execute the Babel command above and what happens is it doesn’t do anything, it just copies the code somewhere else. Babel does not transform code until plugins (plugins) or presets (a set of plug-ins) are specified for Babel.

Babel configuration is usually implemented by creating configuration files. There are two configuration file formats available in Babel 7.x:

  • Json file. Supports.js,.cjs,.mjs extensions. It will be called **babel.config.json** in this article.

  • File-relative configuration: use.babelrc.json files (.babelrc is an alias of.babelrc.json), also support different extensions.js,.cjs,.mjs. It will be called **.babelrc.json**.

The two profiles can be used together or independently. If you want to run some conversion plug-in on a file or a subset of a directory, use.babelrc.json. Adding babel.config.json can be useful if your project has multiple packages (i.e., multiple package.json) directories and requires a separate Babel configuration, which is often the case in monorepo projects where there are multiple subpackages within a project and there are dependencies between the subpackages. Use of Babel for this scenario is described below. If it’s just a regular project (a project is a package), use.babelrc.json.

Json works for the entire project, including node_modules. Babel.config. json is shared in sub-packages as a common configuration, and each sub-package can also make a personal configuration item.

Configuration options

This section describes the common configuration items in general projects. You can view all configuration options here.

//.babelrc.json {// List of plug-ins. See 👇 "plugins": [], // preset list. See 👇 "presets": [],}Copy the code

Description of configuration items:

plugins(plug-in)

Plug-ins are small JavaScript programs that tell Babel how to transform code.

Babel’s transcoding function is enabled by applying plug-ins (or presets) to configuration files.

Babel compiles code in three stages:

  1. Parse: Parses code strings into AST (abstract syntax tree);
  2. Transform (transform: The AST is still the AST after the transform;
  3. Generate: Generate a code string from the transformed AST.

The Plugins are divided into Syntax Plugins and Transform Plugins. The names of the official syntax plug-in and transformation plug-in start with @babel/plugin-syntax and @babel/plugin-transform, respectively. The syntax plug-in acts on the parser (@babel/ Parser) in the parsing stage to expand its syntax parsing capability, and realizes code conversion through the conversion plug-in. If you have configured the appropriate transformation plug-in, you do not need to specify the syntax plug-in because it is automatically enabled, so references to the Babel plug-in usually refer to the transformation plug-in.

For example, add @babel/plugin-transform-arrow-functions to parse and convert arrow functions:

{
  "plugins": [
    "@babel/plugin-transform-arrow-functions"
  ]
}
Copy the code

Source:

var a = b= > b;
Copy the code

After the transformation:

var a = function (b) {
  return b;
};
Copy the code

presets(the default)

Represents a collection of plug-ins.

If you want to compile ES2015 (ES6) code into ES5 using Babel, you need to configure many plug-ins, and installing them one by one is inconvenient. It is especially easy to use the Babel preset @babel/preset- ES2015 because it contains all the plug-ins for the ES2015 feature.

npm install @babel/preset-es2015 --save-dev 
Copy the code
Json {"plugins": [], "presets": ["@babel/preset- ES2015 "], // This option is about to be preset. "env": { "development": { "presets": [["@babel/preset-react", { "development": true }]] } } }Copy the code

In Babel 7, all stage-x presets (babel-preset- ES2015, babel-ES2016 ~ babel-preset-latest) have been preset, Use @babel/preset-env (see 👇) instead.

Plug-in sequence, pass parameters

Plug-in order

The order of the plugins is important. If both conversion plugins will process a certain piece of code, it will be executed according to the following rules:

  • Plugins run before default;
  • Plugins are arranged from front to back;
  • The default order is reversed (from back to front).
{
  "plugins": ["pluginA", "pluginB"],
  "presets": ["presetA", "presetB"]
}
Copy the code

Execution sequence: pluginA => pluginB => presetB => presetA

Passing parameters

Plugin parameters and default parameters are passed in the same way, with the plugin name/default name and parameter objects as an array set in the configuration:

{" plugins ": [" pluginA," [" pluginA, "{" option1" : value}] / / pass parameters], "presets" : [" presetA, "[" presetA," {" option1 ": value }] ] }Copy the code

Monorepos project

There are multiple subpackages in the Monorepos project. Babel.config. json and.babelrc.json can be used together. Here are some common configuration options for monorepos scenarios:

{
  // Inherits the configuration from other configuration files. The configuration fields in the current configuration file are merged over the configuration in the extended file.
  "extends": String.// Specify that this applies only to configurations of certain subdirectories in the repository
  "overrides": [].// Matches a directory or file. Usually used with overrides
  "test": MatchPattern | Array<MatchPattern>,
  // Babel by default does not load.babelrc.json in any subpackages unless the babelrcRoots option is configured in babel.config.js.
  // For example, ['.', './ Packages /*'] enables.babelrc.json loading for the current root directory and all subpackages.
  "babelrcRoots": [],}Copy the code

The 👇 option below is only allowed as a Babel program option. For example, babel-loader options (see below) and Babel –rootMode=upward.

{// The initial path of the "root" directory, which defaults to opts.cwd "root": // - 'root' : keep the root value unchanged // - 'upward' : automatically locate babel.config.json as the root directory. // - upward-optional: like upward, please. "RootMode ": string, // Babel automatically searches babel.config.json in the "root" directory as the project scope configuration by default. This option can specify the project scope configuration file to override the default search behavior. "configFile": string | boolean, }Copy the code

Use the above configuration options with a monorepos project (following directory structure) :

. ├ ─ ─ packages │ ├ ─ ─ package - a │ │ ├ ─ ─ the SRC │ │ │ └ ─ ─ index. The js │ │ ├ ─ ─ the babelrc. Json │ │ └ ─ ─ package. The json │ │ │ └ ─ ─ Package - b │ ├ ─ ─ the SRC │ │ └ ─ ─ index. The js │ ├ ─ ─ the babelrc. Json │ └ ─ ─ package. The json │ ├ ─ ─ Babel. Config. The json └ ─ ─ package. The jsonCopy the code

Babel 7 introduced the concept of root, which defaults to the current working directory (process.cwd()). Babel will automatically search for the babel.config.json file in this root directory, and specifying the “configFile” option can override this behavior by specifying the project scope configuration file.

It is generally possible to place the Babel configuration for all subpackages in the babel.config.json directory in the “root” directory, with the “overrides” option to configure some subdirectory files in a project independently. For example, “@babel/preset-env” in 👇 babel.config.json is preset to be shared, But with automatic mode conversion of the JSX elements in Package-A (introducing the React/JSX-Runtime module), Files in other packages use the classic transformation (converting JSX to a react.createElement call).

// babel.config.json
{
  "presets": [
    "@babel/preset-env",
    ["@babel/preset-react", { "runtime": "classic" }]
  ],
  "overrides": [{
    "test": "./packages/package-a",
    "presets": [
      ["@babel/preset-react", { "runtime": "automatic" }]
    ]
  }]
}
Copy the code

@babel/preset-env 和 @babel/preset-reactDetailed use of can be viewedBabel plugins and presets.

The above configuration will cause problems if you want to run Babel in a particular subpackage (when the current working directory is inconsistent with the Babel “root” directory). For example, if you run webpack in CD./packages/package-a, you will get an error.

Go to babel-loader 👇, rootMode: ‘upward’ means that Babel automatically looks up at babel.config.json as the ‘root’ directory location (the value of the root option).

module.exports = {
  mode: 'development'.module: {
    rules: [{test: /\.(js|jsx)$/,
        loader: require.resolve('babel-loader'),
        options: {
          rootMode: 'upward',}}]}};Copy the code

Babel does not load.babelrc.json in any subpackages by default. Babel.config. json will not be enabled until babelrcRoots is set. The following configuration enables the.babelrc.json file configuration for all subpackages. This option is usually used in place of the Overrides option to personalize subpackages.

{
  "babelrcRoots": ["./packages/*"]
}
Copy the code

Babel configuration options are numerous, see the documentation on the official website for more options.

reference

  • Babel
  • Babel User manual