Large front-end automation plant (3)--babel

Source: Internet
Author: User
Tags addall instance method babeljs


I. About BABEL

babelis the es6+ syntax compiler, official website: Www.babeljs.io, used to convert the old version of the browser unrecognized syntax and features into ES5 syntax, so that the code can apply more environment.

The initial babel use is very convenient, almost only with a small number of configurations can be used, but with the rapid upgrading of tools and code architecture, babel has been fission into a very many parts, each part of their own, The benefit of this is that the development environment can be scaled down by reducing the size of the formal package in the production environment (because it can be referenced on demand), but the disadvantage is that it is very expensive to use with developers who are unfamiliar with the software architecture because of the need to introduce more fragmented plug-ins in the development phase.

For example, the babel official website in the webpack configuration section, mentioned babe-loader , babel-core and babel-preset-env three plug-ins, and when the developer in the webpack actual configuration in addition to the above three basic plug-ins, will encounter babel-polyfill , and babel-runtime babel-plugin-transform-runtime so on a series of plug-ins, Perhaps by looking at the plugin's instructions to understand the functionality of the plugin, it is difficult for developers to determine whether they should use this feature or when to use it.

Two. Basic demand deduction

From the point of view of tool design, we look at the changes by the way of problem deduction babel .

In the ES6 standard launch, the browser is not well supported, but ES6 a lot of features and syntax is very attractive, so people think of a way, that is, to ES6 write code, and then out of the package to take a tool to convert it into a more browser to recognize the ES5 syntax is not OK, so , the Babel basic model appears:

babelfunction is defined as a compilation tool, it is theoretically possible to use the compiler's generic code framework, with Astparser------traverse--- stringify steps to implement the compile function, in a key traverse session, A set of rules is required, but the standard of transcoding is ES6 not a standard for finalization, and each of these features needs to be formally finalized in 5 stages, from stage0 to stage4 , only stage-2 the above-mentioned features of the draft (draft) phase will be supported in the future, while the criteria below this stage are likely to be discarded, and if all conversions are made, it will not only reduce the efficiency of the tool, but will also cause pitfalls for future maintenance of the code.

So if we have a factory function that takes the number 0-4 as a parameter and then returns all of the rule sets that went through the stage-x (a ES6 subset of the rules) as a rule set, you can reduce the code volume when you eventually generate the code for your production environment, if you babel_get_es6_by_stage(2)Such a function returns the ruleset, so the implementation code for stage-0 and stage-1 is not required in the formal code. Based on the above considerations, we Babel perform the first function stripping of the tool:

Deduction continues, after a volume reduction of the ruleset, we get a relatively thin set of rules, which contains many new syntax and methods, if used directly that is really cool, after all, the introduction of a tool can have no worries about the use of new features, but for the production environment of the Code package, The code redundancy caused by this practice is very difficult to accept.

In bootstrap the case of everyone familiar with bootstrap.min.css it, the volume is about 120k , but you will find that many people introduce it entirely out of the mind inertia, and in the end only use very basic btn related style classes, or just to use the col-md-4 style of this responsive layout, All the styles used may take up only 20k-30k space, but they have to introduce a 120k library for the project, and not all projects will care about the difference between 20k and 120k.

Then we need a method that can be combined in a smaller granularity babel_get_es6_by_rules([rule , ...]) , allowing the user to choose the syntax and method they use to reduce the size of the reference library:

The deduction continues. Developers dealing with compatibility issues know that browsers are version-differentiated, many features are implemented and behave differently in different browsers, and for ES6 this, ES6 some of the features in the newer browsers have been implemented incrementally, If the operating environment used by our target users ES6 has already provided native support for some features, or if the target user's operating environment is simply encapsulated by the developer, there will be a lot of unnecessary parts in the original "Yiguoduan" Transcoding method.

For example, if you choose to transcode a keyword to define a class in a rule set, Babel will need to transcode Class it to be used function and prototype ES5, but if your target users are all programmers, Almost all using a high version of Chrome as the project environment, the above transcoding may be superfluous.

To sum up, we need to provide a way for Babel to determine whether the target environment needs transcoding, babel_get_rule_as_need( rule_set , env_info) passing the first filtered rule set and the target user's environment information into the method, the rule set is again streamlined, then we need to optimize the Babel again:

At babel this point, you have the ability to do the necessary transcoding for different use environments, but this is not the whole problem, ES6 new features in addition to the syntax of the update, but also added a lot of native methods or types, such as, such as such Map Set Promise new Global objects, or Array.from This kind of static method, and so on, syntax escaping does not complete the recognition of these features, because both in the ES5 environment or the ES6 environment you write this, only when the browser will be running, you can tell you that an object or a method does not exist.

For example, the following code:

function addAll() {  return Array.from(arguments).reduce((a, b) => a + b);}

When escaped, it becomes:

function addAll() {  return Array.from(arguments).reduce(function(a, b) {    return a + b;  });}

However, it is still not available anywhere because it is not supported by all JAVASCRIPT environments Array.from . For this class of non-grammatical features, we want to be able to provide support automatically in the tool, which has a proprietary title called "Polyfill"(or "shim").

We can either proactively provide an array of shim inserts that need to be added, or you can use a passive way to put an array of this type of new feature encountered in the transcoding process, API by installing the appropriate shims for the Polyfill, it is important to babel_add_polyfill ( polyfill_list ) note that Polyfill is equivalent to extending the functionality of the browser, which takes precedence over the project business logic code, then the Babel logical framework becomes:

Deduction continues. In the above logical structure, we simply add the Polyfill library to the global variable, and the global variable is most likely to be rewritten to fail or conflict with other third-party libraries. So if you don't add Polyfill to the global, you need to split it into a separate module with equivalent functionality, and call it in a similar lodash way or another underscore , and we'll split the logical structure again:

At this point, we have completed the Babel toolset basic functions of the * Logical layer Division *, through the legend of the multi-back less complement (that is, the grammar ahead of the fallback, the method is not enough to hit the patch) way to achieve code compilation.

Three. Module partitioning

Based on the division result of the above business logic layer, we need to divide the code layer of the Babel tool into modules:

Four. The real Babel

If you can understand the above requirements deduction and Module Division, then congratulations you have mastered the basic structure of the Babel, we will be the original module diagram of the information to replace the actual name or plug-in, and some component division, you can see the basic structure of the real babel toolset:

Of course, the real babel function is much more than that, it provides interfaces for various environments, editors and automation tools, and also opens the plug-in development API to the developers, interested readers can continue to understand deeply.

Five. Using Babel

babelMore than 8.0 of the version to move many plugins into the official warehouse, the installation method has changed, such as the babel-preset-env address changed @babel/preset-env , please refer babel to the official website for configuration.

1.babel-cli

To facilitate the ability to use Babel directly at the command line, yarn global add babel-cli add the following script to Package.json by babel-cli the command-line tool in the global installation:

"scripts":{    "babel":"babel main.js -o maines5.js"}

It can then be yarn run babel compiled by using Babel at the command line, but looking at the compiled code will reveal that the files before and after the compilation are the same, because we did not specify any transcoding rules for them, and running Babel just traversed the resulting AST. If you want Babel to be able to implement transcoding, continue looking down.

2.babel-preset-env

Provides transcoding rules, a babel combination of several plugins used in its lower version. In babel-preset-env fact, the "all rules rule set + get_rules () method Set"that we describe in the problem deduction, you will node_modules find many babel-plugin-transform-*** of these named packages in the folder, they are the rule sets, you can either set the presetproperty, or you can refer to it by plugins selecting the required transcoding rule in the attribute.

babel-preset-envafter installation, create a new file in the project folder .babelrc and add the following configuration:

{    "presets":["env"],    "plugins": []}

Or customize the escape rules that you need to support:

{    "presets":[],    "plugins": [        "babel-plugin-transform-es2015-arrow-functions"//箭头函数转换规则    ]}

Running again babel , you can see that the code you have written has been converted.

Before conversion:

//Arrow Function  Array.from methodArray.from([1, 2, 3]).map((i) => {    return i * i;});

After conversion:

"use strict";//Arrow Function  Array.from methodArray.from([1, 2, 3]).map(function (i) {    return i * i;});

Of course, you can also specify the target browser to remove unnecessary transcoding, for example, to .babelrc specify a higher version of Chrome for the browser to match:

//.babelrc{    "presets":[         ["env", {          "targets": {             "browsers": "chrome 56"          }              }]    ],    "plugins":[]}

You can find that the arrow functions in the compiled script file still exist, indicating that this version of the chrome browser has support for the arrow function, there is no need to escape.

The new version of Babel has been planned to support setting parameters in Package.json browserslist To specify the usage environment that needs to be adapted, which means that the same set of configurations for the usage environment is stripped out and postcss used for babel autoprefixer shared use by tools.

3.babel-polyfill

Babel is only responsible for syntax conversions, such as converting ES6 's syntax to ES5. But if there are objects or methods that the browser itself does not support, such as:

    1. Global objects: Promise, Weakmap, and so on.
    2. Global static functions: Array.from, Object.assign, and so on.
    3. Example methods: such as Array.prototype.includes.

At this point, you need to introduce a babel-polyfill simulation to implement these objects, methods.

If the above compiled code is opened in the IE10 browser, you will see the browser does not support the Array.from method error, if the generated code needs to IE10 run in, then we need to introduce a compatible patch library, so that IE10 the browser environment can support this method.

babel-polyfillIt needs to be introduced in such a way that it can be incorporated into the script using the packaging tool:

//ES Moduleimport 'babel-polyfill'//或 CommonJsrequire ('babel-polyfill')

When you do this, you will find that it does solve the problem of error, but it is hard to accept that packaging will introduce the whole babel-polyfill , and the packaged code adds nearly 4000 lines (about 400k volume increments). Can this plug-in babel-preset-env be like the same as on-demand reference? Must be able to. babel-polyfillis based on core-js and regenerator built, and only needs to be indicated at the time of reference, for example:

import 'core-js/modules/es6.array.from';//Arrow Function  Array.from methodArray.from([1, 2, 3]).map((i) => {    return i * i;});

When you package it, you'll find that the bundle file size is much smaller.

babel-polyfillImplementation, as mentioned in the problem deduction, is polluting the global environment, and you may already realize that this tool, either simply configured after a surge in code, or on-demand reference configuration cumbersome. It is not recommended unless there is a requirement for low-version IE in medium-sized projects.

4.babel-runtime/babel-plugin-transform-runtime

If a thing is difficult to use, then soon there will be a substitute, the software of the world is such babel-runtime a substitute. Extract the explanations in the blog post recommended below:

  • Babel-polyfill

    Simple and rude, he will pollute the global environment, for example, in a browser that does not support promise Polyfill a global promise object for invocation, and an unsupported instance method adds a method to Polyfill on the corresponding constructor prototype chain.

  • Babel-runtime

    Does not pollute the global environment, it will be polyfill locally, and will not convert some instance methods , such as ' abc '. Includes (' A '), where the includes method is not translated. It is generally combined babel-plugin-transform-runtime to use.

In short, other features, in addition to the instance method, babel-runtime will help you fix the patch. Add it directly to the configuration item when you use it plugins babel-plugin-transform-runtime .

In General, babel-polyfill and babel-plugin-transform-runtime all have their own use of the scene, but also can be used in combination with the actual project needs to be screened and introduced .

Six. Information recommendation
    • "Webpack+babel project in IE report promise undefined error leads to thinking"

      It detailed explanation babel-runtime of the babel-plugin-transform-runtime related issues.

    • "How to write good. BABELRC?"

      It detailed explanation of the various configuration items and optional parameters of the meaning, very practical.

    • Starter Guide: Babel-handbook

      A great starter guide that explains the concepts and usage in Babel, and suggests a priority reading to help developers understand the Babel modules that are not covered in this article.

    • Official website: Www.babeljs.io

      Many developers like to watch the tutorial but easy to ignore the official website, which is very strange. The official website will link to very good github warehouses, including not only the underlying modules in the Babel package, but also the Web sites that help us understand the guiding repositories and even ES2015 the main features, which are the main resources for learning Babel.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.