Writing in the front

I usually use scaffolding tools for daily development, but there are a lot of situations where I want to configure something myself, and I don’t have a clear idea of how to configure it. So I decided to write a step-by-step tutorial on Babel. I typed and experimented with every word here. If there is anything wrong, please point it out

Initial Installation

mkdir learn_babel && cd learn_babel

npm init -y 

mkdir src && cd src && touch app.js

npm install --save-dev @babel/core @babel/cli
Copy the code

Write test code

const abc = () = > {
  console.log(`this is abc`);
}
Copy the code

** This line of code contains three es6 advanced syntax: const, arrow function, template string

Run NPX Babel SRC /app.js and you’ll find that Babel doesn’t do any conversion for us. By default, Babel doesn’t do any conversion for us. We need to install a series of plugin modules to support different advanced syntax features.

Learn_babel git:(master) qualify NPX Babel SRC /app.js const ABC = () => {console.log(' this is ABC '); };Copy the code

Installing a plug-in

It says that we are using three advanced syntax. Ok, let’s try installing three plug-ins one by one.

npm install --save-dev @babel/plugin-transform-block-scoping @babel/plugin-transform-template-literals @babel/plugin-transform-arrow-functions
Copy the code

Then run NPX Babel SRC /app.js again and you will find that there is no change. At this point you need to configure the above three plug-ins to work. Create a.babelrc file in the root directory, run the compilation again, and you’ll be surprised how much code you want

{
  "presets": []."plugins": [
    "@babel/plugin-transform-arrow-functions"."@babel/plugin-transform-template-literals"."@babel/plugin-transform-block-scoping"]}Copy the code

The preset

The above seems to have achieved the goal, but ah but, a few lines of code, need to install so many plug-ins to support, just think of ES6+ so many new features, it would be tiring to install one after another. Yes, Babel offers us a great value plan. It’s like when you go to your mobile phone to do business. If it takes time and effort to do business one by one, you might as well just go to the plan

npm install --save-dev @babel/preset-env
Copy the code

The babelrc configuration file is as follows:

{
  "presets": ["@babel/preset-env"]."plugins": []}Copy the code

The package is ready for you now, but sometimes you can make some extra configuration based on your situation and avoid useless compile-wasting performance. For example, you only need to support Google Chrome, so you don’t need to switch to lower versions of IE at all. So @babel/preset-env can specify browser support configuration. You can configure your browser support by creating another.browserslistrc in the root directory:

defaults
not IE 11
maintained node versions
Copy the code

NPX browserslist doesn’t support IE11. Run NPX Babel SRC /app.js again and you’ll see that it won’t compile because other browsers with higher versions of Internet Explorer already support this basic syntax. If you want to support IE, you can change the configuration to:

defaults
ie > 10
maintained node versions
Copy the code

Run the above command again and you will see that it has compiled the lower version syntax for you.

Gasket or patch

It has solved the question turns on advanced grammar low-level, but ES6 + not just added some grammar, it also adds a lot of advanced apis, such as: Array. Prototype. Includes, change the SRC/app. The js code:

const arr = [1.2.3.4.5];
console.log(arr.includes(1));
Copy the code

When you compile again, you find that the const is compiled, but includes is printed as is, so it still won’t run in Ie. A shim is needed to help us accommodate advanced API extensions that browsers don’t support themselves. This package is actually a core-js&Regenerator-Runtime/Runtime combination.

npm install --save @babel/polyfill
Copy the code

Then change some SRC /app.js code,

import "@babel/polyfill"; Const arr = [1, 2, 3, 4, 5]; console.log(arr.includes(1));Copy the code

When you compile, the import syntax is not fully translated into some of the function definitions you would expect so far, but it is translated into the following code

"use strict";

require("@babel/polyfill");

var arr = [1, 2, 3, 4, 5];
console.log(arr.includes(1));
Copy the code

Why is that? Since Babel only does code conversion by default, it doesn’t do module packaging for you, so if you want to see results, you may need to use rollup or Webpack in conjunction with Babel to do module packaging. I wrote a simple example of rollup earlier: record rollup with Babel for code packaging

Of course, the above configuration may import all the spacers at once, so we can change the babelrc configuration to implement the load on demand:

{
  "presets": [["@babel/preset-env",
      {
        "useBuiltIns": "usage"."corejs": 2}]],"plugins": []}Copy the code

Compile it again, you will find all the require is no longer a @ Babel/polyfill, but the core – js/modules/es7. Array. Includes. Js

transform-runtime & runtime

Because can’t see the results after the package above, here is to explain, is actually the prototype of the gasket can change some built-in objects directly, so at some point if no problem, but if is to develop some library files, modify the object prototype directly, certainly is not good, because the future others to use your library can also modify the object prototype of the user, the global pollution. So we want to define these high-level apis in a private way.

npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
Copy the code

Then modify the. Babelrc configuration

{
  "presets": [["@babel/preset-env",
      {
        "useBuiltIns": "usage"."corejs": 3}]],"plugins": [
    "@babel/plugin-transform-runtime"]}Copy the code

Then modify SRC /app.js

class Person {
  constructor(name){
    this.name = name
  }
}

let p = new Person('tom')


let arr = [1.2.3];
console.log(arr.includes(1));

Copy the code

You can see how it works by not configuring @babel/ plugin-transform-Runtime

  • If no configuration is required
"use strict";

require("core-js/modules/es7.array.includes.js");

require("core-js/modules/es6.function.name.js");

function _classCallCheck(instance, Constructor) { if(! (instanceinstanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); }}var Person = function Person(name) {
  _classCallCheck(this, Person);

  this.name = name;
};

var p = new Person('tom');
var arr = [1.2.3];
console.log(arr.includes(1));
Copy the code
  • Configuration situation
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));

require("core-js/modules/es6.function.name.js");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));

var Person = function Person(name) {(0, _classCallCheck2.default)(this, Person);
  this.name = name;
};

var p = new Person('tom');
var arr = [1.2.3];
console.log((0, _includes.default)(arr).call(arr, 1));

Copy the code

You’ll notice that _classCallCheck and _classCallCheck2 are either generated directly or imported from the Runtime; And configuration after the runtime also generates a _includes function, instead of directly using the core – js/modules/es7. Array. Includes. Js, thus has solved a series of problems.

The last

So much for the Babel tutorial series, but if you’re interested, you can also read about packaging tools to build development environments with Babel, such as the one I wrote above on rollup. Finally, if there is something wrong, please point it out! I put the code address here: gitee.com/hellohere/l…

reference

Babel’s official website

browserslist

Record rollup’s code packaging with Babel