Closure Compiler Advanced mode and more thinking

Source: Internet
Author: User
Tags define object execution function definition functions variables string variable

Objective

Google Closure Compiler, a member of Google Closure Tools, was Google at the end of 2009
Released, earlier, with Yuber Closure Compiler vs. Yuicompressor, mainly on the compression rate
On the other hand, the application of closure compiler advanced mode, the CC
The advanced mode of the introduction.

This article will introduce the Advanced Mode section of CC in detail, and more importantly, explain the thinking behind the CC advanced mode

CC is the real compiler.

Closure Compiler and Yuicompressor are not similar products, although CC and YC also output compressed JS files,
But YC only does the lexical scan, and CC is not just a compressor so simple, the device as its name, it is a
Compiler

For a compiler, generally, it needs to be done

    1. Check the source text for grammatical, semantic, and pragmatic errors
    2. Output target/intermediate code based on analytical output (symbol table, syntax tree, etc.)
    3. Optimization

Code errors generally come from three aspects:

    1. Syntax (Syntax)

      A combination of symbols that make up a language sentence

      In general, Parser/interpreter in the lexical analysis and parsing phase, the production of symbolic tables, syntax trees and other analytical outputs,
      See the textbook of compiling principle ...

      Grammatical errors, such as:

      doSomething(;) // SyntaxError: Unexpected token ;
      

      According to the grammar rules, the meaning in the non for statement ; is the delimiter, and the front of the separator is ( not paired ) ,
      So the error

    2. Semantics (semantics)

      Represents the specific meaning of each token (the relationship between the objects represented by each mark and token)

      compiler needs to produce intermediate code based on semantic analysis, for languages that do not produce intermediate code such as JS, at runtime
      Error indicated during interpretation

      Semantic errors, such as:

      0 = {}; // ReferenceError: Invalid left-hand side in assignment
      

      The = left-hand operand cannot be literal, depending on the meaning of the assignment operator, so although the assignment statement contains the required
      Left operand, operator, right-hand operand, still error

    3. Pragmatics (pragmatics)

      Represents the origin, use, and impact of the actions that appear in each sign

      A pragmatic error, as in:

      doSomething(); // ReferenceError: doSomething is not defined
      

      An undefined function was called directly here, causing an error

In some other scenarios, while the program is running correctly, it can still be optimized (this optimization is not a technique), such as:

function doSomethingElse() {}
(function() {
    return;
    doSomethingElse(); // No Exception but Redundant: Unreachable code
})();

Here, the Dosomethingelse function has a return before it, so this function call will never execute, this redundant code
is useless for the entire program and can be removed

For Closure Compiler, it handles JS and does not need to generate other intermediate or assembler code/machine code,
So the output or JS, but is analyzed, optimized JS, in addition, it can also choose to output parse tree (using
–print_tree parameters), so CC does accomplish what a compiler needs to implement

CC Feature Overview

Before we discuss the advanced mode of CC in detail, we will briefly introduce the functional system

Compilation level

The compilation_level of CC includes three levels:

    1. Whitespace_only

      Delete only whitespace, comments

    2. Simple_optimizations

      Convert local variables and parameters to short names based on Whitespace_only

    3. Advanced_optimizations

      More aggressive renaming, removing garbage code, inline functions

As you can see, the simple_optimizations level CC, and YC is no different, did not do any real compilation work, so say,
CC with Advanced mode is the CC = of the healthy limbs. =

Constraint conditions

The use of CC has certain constraints that affect our coding style:

    1. Whitespace_only

      • does not recognize JS 1.5 version of the language characteristics
      • Do not keep comments
    2. Simple_optimizations

      • Completely disabled with andeval
      • Function name/parameter name referenced in string will not change (CC does not change all strings)
    3. The constraints in the Advanced_optimizations mode are set out in detail below

Annotations

Annotations is also an important component of CC, using the JSDoc style to assist in advanced mode compilation, detailed below

Using CC Advanced Mode

Under CC, the way to enable advanced mode is to add parameters--compilation_level ADVANCED_OPTIMIZATION

As a COMPILER,CC advanced model, the additional optimization policy is

    1. More aggressive renaming, such as Obj.property change to a.b, flattening the namespace of the depths too high
    2. Remove garbage code, such as deleting a method definition that is not invoked, warning logical dead ends (statements after return, etc.)
    3. Inline functions, such as a call B, B call C,a (), then direct execution C ()

To achieve the expected optimization effect of advanced mode, developers must make some constraints on themselves, because JS is weak type, dynamic. Otherwise
JS This flexibility will make compiler powerless

In general, this constraint includes qualifying certain JS coding styles and using the corresponding JSDoc annotation

The following details the specific constraints and the inspection/optimization effects of the code:

Strongly-typed impersonation

    • Types defined in @param and @type are checked during compilation and also avoid run-time checks to improve performance

    • @const tag constant that will error when the constant is written

    • Simulates an enumeration, defines the same enumerable constants as an object literal, and uses @enum tags:

      var STATUS = {
          LOADING: 3,
          COMPLETE: 4
      };
      

      The result of the compilation STATUS.LOADING is replaced directly with 3, which actually simulates the enumeration in languages such as C.

    • Using the @constructor callout function as the constructor, it can only be instantiated and not used as a common method.
      even the factory method , CC will ensure that the constructor is used legitimately, otherwise the error. This ensures that developers do not have to run
      To determine how the constructor function is invoked in exactly the form

    • You can also use @type to qualify types in an expression, which is especially useful for JSON, such as

      var data = /** @type {UserModel} */({
          firstName : 'foo',
          lastName : 'bar'
      });
      

      Here Usermodel is a constructor, or you can use @typedef to customize complex data types

Simulation of domain visibility

    • Use @private to annotate private domains, and private fields will be error-referenced by external references. Developers can also follow "international practice" to the private domain plus
      _prefix or suffix to remind yourself/collaborators this is a private domain, @private annotations are used to tell CC;
      In this way, developers do not have to use such techniques as sophisticated "modular mode" to really hide private variables, leaving the inspection work to
      CC, make the development as simple as possible

    • Similar to a @protect

Simulation of class System

    • Inheritance relationships are optimized using @extends annotations.

    • Using the @interface callout interface, the interface is similarfunction ThisIsAInterface(obj) {}
      function body is an empty constructor definition, and its associated code is removed after compilation. At the same time, the constructor for callout @implements must implement
      Implemented all the methods of the interface (as in other OO languages), otherwise CC complains. This also simplifies the interface/
      Implementation of constraints, by CC to ensure the reliability of the relationship

Simulation of conditional compilation

    • Use the @define tag status switch, which is suitable for debugging logger and other development/release states that need to be detached.
      You can specify parameters at compile time to identify the state of the Define parameter. This is actually a conditional compilation, really to force ...

Flattening of objects and reduction of attribute names

    The
    • Object property is compiled to a single variable, such as Foo.bar to Foo$bar , which looks much like the inner class that was compiled in Java
      ~ ~ after foo$bar was Further shortened. objects can be flattened because objects in
      JS can be viewed as a container of reference/RAW data types

    • However, the JS object is actually more complex, so flattening will have some side effects, such as if you use the
      thi in the object (literal) s pointer, the compiled result causes this to point to an error. So Google recommends using this only in constructor and
      prototype methods, which means that you avoid using thi in the so-called class single (object literal) and static methods of classes (which are bound to functions on
      constructor) s pointer

    • When reducing the length of the name of an object property/method, there is another point of attention, that is, you must always use the dot syntax (.
      operator), rather than using the quoted string ( [] operator) unless the index name is a variable. This is because CC
      always does not handle the contents of the string , so var o = {longname:0}; o["LongName"] is translated to
      var a = { B:0}; a["LongName"] causes an error. If you really want to use quoted string, at time
      also use quoted string

    • For global variables, if they appear to be referenced in Window.property, you must always set the The meaning is window.porperty form:

        window.property = 1; var property = 1;//wrong!  

      Otherwise there will be cups, CC will not window.property translated to WINDOW.A

Removal of garbage code

    • When a function declaration is not invoked, by default, the body of the declaration is killed

    • Under this mechanism, if a method is called in the form of for, the original method is also killed because the dynamic feature
      Makes CC not clear if the method is actually invoked for

    • For some unreachable code, CC will report a warning

    • If you want to produce a public interface called, such as a library, export the function using a method called export , preventing the function definition from being
      CC Recycle. The specific approach is to bind the function to a container, such as:

      function displayNoteTitle(note) {
          alert(note['myTitle']);
      }
      // Store the function in a global property referenced by a string:
      window['displayNoteTitle'] = displayNoteTitle;
      

      For functions that need export, use the quoted string style

Behind the Thinking

According to the above Advanced mode optimization behavior analysis, CC attached to the developer's main constraints are:

    1. Forced to write JS in a strongly typed static language style, shifting focus from run-time dynamic techniques to organizing code, writing logic
      Itself.

      The problems and risks that may arise from weak-type systems and dynamic features are given to CC, which is achieved through a developer and CC
      Coding conventions and avoiding

    2. Strict requirements distinguish between developer-oriented code and machine-oriented code .

      Although not like C and other languages will compile the target code, but CC to some extent also generates a machine-oriented JS,
      Includes compressed whitespace, reduced identifiers, conditional compilation, and redundant code removal.

      This is in fact in the same vein as the 1th, requiring developers to shift their focus to development .

    3. Use a normalized interface method.

      This includes not only asking developers to use the appropriate annotation (extend, interface, ...). ), but also to the whole OO-JS
      Lays out a framework that developers must use the same pattern for OO coding

      In addition, the requirement to use export technology to unify the export of public interfaces reinforces this point

      In short, this further defines the developer's coding style, but the benefits are obvious: readable, controllable, consistent

Once read Closure Library source code of the classmate commented:

Google doesn't know how to write javascript!. The code inside a variety of redundancy, and full of Java flavor!

I did have this feeling at the time, such as Google if(foo) writing if(foo != undefined) and so on

Javascript is full of dynamic features, and many features are elegant enough to make the code concise, or to construct some
Amazing technique, but it can also have some side effects:

    • The first problem is readability, static things easy to see, dynamic things need to go through some operation to come to a conclusion.
      such as the extremely late binding in JS, again such as the identifier runtime rewrite

    • The second problem is execution performance. One of the more classic JS engineers are using the technique is " analog function Overload "--
      The characteristics of arguments are judged in the function body, thus the different logic is given. Because of the lack of strong type, JS itself can not have
      The real overload, but the run-time judgment in the flexibility of the same time, there will be many more simulated overload logic, reduce performance

At this year's D2 conference, Hedger students pointed out that most JS developers like a Ninja (ninja), their skills,
Shenthomo, it's okay to fight solo, but once you hit Army (the army, like the Google team, =,=) is a tragedy.

I appreciate this analogy, the large team to work well together, must follow certain norms and constraints, priority to ensure readability and consistency, while
Lost is Chine, free and flexible. So what kind of programming style, concept, need concrete analysis of specific problems ...

At the very least, CC offers a good idea at the moment, and its advanced mode is highly valued for its programming style, which is worth trying and drawing on.

Finally, attach the common command options for CC ... There are really plenty of options ...

CC Common Command Options

    • –charset VAL defines the encoding format for all files
    • –compilation level[whitespacea simpleoptimizations ADVANCEDoptimizations]
      Set compilation level
    • –debug Turn on the debug option
    • –define (–D, D) VAL The switch value used @define callout in the set file, that is, conditional compilation
    • –externs VAL When compiling code needs to invoke an precompiled code, use it
    • –formatting [Prettyprint printinput_delimiter] formatted output
    • –js VAL input file, specify more than one, will be merged
    • –jsoutput file VAL outputs files, if not specified, direct output to standard output stream
    • –module VAL Definition Module
    • –output_manifest VAL Print compiled file list
    • –print_tree Print Syntax Analysis tree
    • –warning_level [QUIET DEFAULT VERBOSE] Set the error mode


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.