6

I have been reviewing the code for a past project prior to implementing some new features. One of the objectives was to simplify the management of the code by migrating it to ES6 modules. This has gone well, and makes life a great deal easier.

However, during the process of building the final application we have been using Google's Closure Compiler to minify the code. This was working well, but now...

Take this sample HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTML file to test compilation of JS modules</title>
</head>
<body>

<script src="JSModule1.js" type="module"></script>
</body>
</html>

and add these two modules

JSModule1.js

import {Thing} from './JSModule2.js'

let item = new Thing('Something');
let otherItem = new Thing();

item.speak();
otherItem.speak();

JSModule2.js

function Thing(word) {
    let words = (word || "I've nothing to say.");
    this.speak = function() {
        console.log(words);
    }
}

export {Thing}

If I try to compile just JSModule1.js I get an error:

JSC_JS_MODULE_LOAD_WARNING: Failed to load module "./JSModule2.js"

If I tweak the load process to submit both files in the same compilation I get a monolithic block of code incorporating both modules:

function Thing$$module$JSModule2(a){var b=a||"I've nothing to say.";this.speak=function(){console.log(b)}}var module$JSModule2={};module$JSModule2.Thing=Thing$$module$JSModule2;var item$$module$JSModule1=new Thing$$module$JSModule2("Something"),otherItem$$module$JSModule1=new Thing$$module$JSModule2;item$$module$JSModule1.speak();otherItem$$module$JSModule1.speak();var module$JSModule1={};

This is what's sent to the compiler in the query string:

compilation_level=SIMPLE_OPTIMIZATIONS&output_format=xml&output_info=compiled_code&language=ECMASCRIPT6_STRICT&js_code%3A.%2FJSModule1.js=import+%7BThing%7D+from+%27.%2FJSModule2.js%27%0A%0Alet+item+%3D+new+Thing%28%27Something%27%29%3B%0Alet+otherItem+%3D+new+Thing%28%29%3B%0A%0Aitem.speak%28%29%3B%0AotherItem.speak%28%29%3B&js_code%3A.%2FJSModule2.js=function+Thing%28word%29+%7B%0A++++let+words+%3D+%28word+%7C%7C+%22I%27ve+nothing+to+say.%22%29%3B%0A++++this.speak+%3D+function%28%29+%7B%0A++++++++console.log%28words%29%3B%0A++++%7D%0A%7D%0A%0Aexport+%7BThing%7D%0A&output_info=errors&output_info=warnings&output_info=statistics

So, if I want to compile just one module I can't do it. I have to compile it along with any modules it imports. If I do this for a set of modules that each have a number of dependencies then I could end up with more code than if I hadn't compiled them in the first place.

The only approach seems to be to compile the whole application at once, and live with the resulting single block of code.

Now, it seems that I can compile just JSModule2.js without an error, but for the real application the modules have at least one further dependency, and sometimes more, so once again I'm back to compiling the whole thing.

Question: Is there some way I can get the Closure Compiler to compile modules without compiling all the dependencies at the same time?

  • I have exactly the same problem. More than a year has come but there is no any answer. – Edward Feb 17 '21 at 16:30
  • I think you might find your answer here (I've not tried it yet). Closure-compiler [Chunk output for dynamic loading](https://github.com/google/closure-compiler/wiki/Chunk-output-for-dynamic-loading) – Karl Jul 05 '21 at 10:39
  • Also, you can see this SO question with an accepted, updated answer [how do I split my javascript into modules using googles closure compiler](https://stackoverflow.com/questions/10395810/how-do-i-split-my-javascript-into-modules-using-googles-closure-compiler?rq=1) – Karl Jul 05 '21 at 10:59

0 Answers0