Search code examples
javascriptgoogle-closure-compiler

How to get variable from another compressed file with closure compiler


Hello I want to integrate Closure compiler by Google to compress my files with ADVANCED_OPTIMIZATIONS mode but I have 2 compressed files and I need to share variables between both.

I read this documentation https://developers.google.com/closure/compiler/docs/api-tutorial3

Issue

I got this error :

ReferenceError: getValue is not defined

so I tried to replace getValue by window['getValue'] but it does not working.

Basic code

First JS FILE :

var nb0 = 0;
var nb1 = 1;
var nb2 = 2;
var nb3 = 3;

function getValue( nb ) {
    return nb;
}

window['nb0']           = nb0;
window['nb1']           = nb1;
window['nb2']           = nb2;
window['nb3']           = nb3;
window['getValue']      = getValue;

Second JS FILE :

document.addEventListener("DOMContentLoaded", function() { 

    var val = getValue;

    document.querySelector( ".button" ).addEventListener( "click", upButton );

    function upButton() {

        val++;
        document.querySelector( ".show" ).innerText = val;

    }

} );

Solution

  • The solution to this problem is stated, if briefly, under the subheading Solution for Calling out from Compiled Code to External Code: Externs in the document you've linked.

    I imagine your confusion comes from the words "third-party" and "external". In the context of this document, you can assume "third-party" and "external" refers to both code written by others, and any code that comes from any files compiled separately (by you or others).

    The solutions then are either to prepend /** @export */ to the vars you wish not to be renamed, or to define an externs file for your sources.

    Alternate 1

    If you wish to continue using window in this manner (it might be ugly, imho there are times when this is appropriate), you should change

    var val = getValue;
    

    to

    var val = window['getValue'];
    

    For example:

    document.addEventListener("DOMContentLoaded", function() { 
    
        var val = window['getValue'];
    
        document.querySelector( ".button" ).addEventListener( "click", upButton );
    
        function upButton() {
    
            val++;
            document.querySelector( ".show" ).innerText = val;
    
        }
    
    } );
    

    compiles to

    document.addEventListener("DOMContentLoaded", function() {
      var a = window.getValue;
      document.querySelector(".button").addEventListener("click", function() {
        a++;
        document.querySelector(".show").innerText = a;
      });
    });
    

    Alternate 2

    Use ES6 modules. Closure Compiler supports these with the module_resolution flag.

    General reading: Encapsulating Code With Modules :

    Alternate 3

    Use the Google Closure Library's modules (goog.module, goog.require, and (deprecated) goog.provide).