如何使用 Google 的 Closure Compiler 编译 ES6 模块

6 javascript module google-closure-compiler

在实现一些新功能之前,我一直在审查过去项目的代码。目标之一是通过将代码迁移到 ES6 模块来简化代码的管理。这一切进展顺利,让生活变得更加轻松。

但是,在构建最终应用程序的过程中,我们一直在使用 Google 的 Closure Compiler 来缩小代码。这运行良好,但现在......

拿这个示例 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>
Run Code Online (Sandbox Code Playgroud)

并添加这两个模块

JSModule1.js

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

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

item.speak();
otherItem.speak();
Run Code Online (Sandbox Code Playgroud)

JSModule2.js

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

export {Thing}
Run Code Online (Sandbox Code Playgroud)

如果我尝试编译,JSModule1.js我会收到一个错误:

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

如果我调整加载过程以在同一个编译中提交两个文件,我会得到一个包含两个模块的整体代码块:

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={};
Run Code Online (Sandbox Code Playgroud)

这是在查询字符串中发送给编译器的内容:

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
Run Code Online (Sandbox Code Playgroud)

所以,如果我只想编译一个模块,我做不到。我必须将它与它导入的任何模块一起编译。如果我为一组模块执行此操作,每个模块都有许多依赖项,那么与我没有首先编译它们时相比,我最终可能会得到更多的代码。

唯一的方法似乎是一次编译整个应用程序,并使用生成的单个代码块。

现在,似乎我可以毫无错误地编译JSModule2.js,但是对于真正的应用程序,模块至少有一个进一步的依赖项,有时甚至更多,所以我再次回到编译整个过程。

问题:有什么方法可以让闭包编译器在不同时编译所有依赖项的情况下编译模块?