Javascript 闭包编译器编译es6模块库时没有导出符号

Javascript 闭包编译器编译es6模块库时没有导出符号,javascript,ecmascript-6,google-closure-compiler,es6-modules,Javascript,Ecmascript 6,Google Closure Compiler,Es6 Modules,起点:闭包编译器(高级优化级别)在单个库文件中成功编译了许多js文件(无警告/错误) 在这些js文件中: goog.require和goog.provide用于在它们之间导入/导出东西 /**@export*/用于库外所需的任何(const/function/Class/var)前面 一些HTML文件包括库和一些未编译的js,它们可以成功访问库中定义的所有内容 我想要的:移动到es6模块语法 我为每个js文件做了什么: goog.require替换为import,其中包含来自另一个js文件

起点:闭包编译器(高级优化级别)在单个库文件中成功编译了许多js文件(无警告/错误)

在这些js文件中:

  • goog.require
    goog.provide
    用于在它们之间导入/导出东西
  • /**@export*/
    用于库外所需的任何
    (const/function/Class/var)前面
一些HTML文件包括库和一些未编译的js,它们可以成功访问库中定义的所有
内容

我想要的:移动到es6模块语法

我为每个js文件做了什么:

  • goog.require
    替换为
    import
    ,其中包含来自另一个js文件的类、函数列表
  • goog.在另一个js文件所需的每个类、函数等前面提供
    删除和
    导出
    添加
  • 尝试1:每次
    库外需要的
    ,都不更改
    /**@export*/
  • 尝试2:将所有
    /**@export*/whatever
    替换为
    goog.exportSymbol('whatever',whatever)
这是成功编译的(没有警告/错误,仍然具有高级_优化级别)

问题:现在,对于相同的HTML文件,在库中定义的所有
文件都被浏览器视为“未定义”。事实上,当我在控制台中键入
Object.keys(window)
时,我可以看到编译器更改的所有符号名称(
aa
ba
ca
等),但我导出的符号
都没有

示例:
demoVisitors
是在库中定义并在外部必需的
const数组。

在库文件中之前,我可以看到
。。。w(“demoVisitors”,[Oa,La,Ma,Na])并且内容在HTML页面中正确可见。es6模块更换后,我可以看到
。。。H(“demoVisitors$$模块$filemane”,Oa)
filename
是定义了
demoVisitors
的文件名),用于try 1和
H(“demoVisitors”,[Na,Ka,La,Ma])用于尝试2<代码>演示访问者
在同一页面的浏览器中未定义。

经过进一步调查,我找到了解决方案

虽然在浏览器中加载,但控制台中没有任何错误(当然,除了
未定义的任何内容),我的库没有执行。我只是将闭包库移到要编译的文件堆栈之前,然后浏览器正确地执行我的库,并正确地导出我的符号。有关更多详细信息,请参见下文

导出符号的3种方法在已编译的es6模块中工作:
/**export*/whatever
goog.exportSymbol('whatever',whatever)
window['whatever']=whatever
。前两个是第三个(根符号)的简便方法

然而,
/**@export*/myClass
会生成一个不友好的未混淆名称,如带有路径的
myClass$$module$源文件名。
为了获得未混淆的名称
myClass
,避免代码中出现
goog
函数,并灵活地启用编译/未编译模式,我删除了
/**export*/
,并在
类myClass{…}
之后添加
未混淆的符号('myClass',myClass)
。这是我“自己”的函数,直接灵感来源于闭包库中定义的
exportSymbol
函数。这仅适用于类等根符号,您可以为类中定义的所有符号(属性、函数等)保留
/***@export*/

以下是源代码:

export function unobfuscateSymbol(publicPath, object, objectToExportTo = window) {
    // Same code can be used compiled and not compiled so unobfuscation only in case of obfuscation
    if (unobfuscateSymbol.name !== 'unobfuscateSymbol') {
        const /** Array<string> */ parts = publicPath.split('.');
        let /** Object */ objToExportTo = objectToExportTo;
        let /** string */ part;
        const /** number */ nbOfParts = parts.length;
        for (let /** number */ i = 0; i < nbOfParts; i += 1) {
            part = parts[i];
            if ((i === (nbOfParts - 1)) && object) {
                objToExportTo[part] = object;
            } else if (objectToExportTo[part] && objectToExportTo[part] !== Object.prototype[part]) {
                objToExportTo = objectToExportTo[part];
            } else {
                objToExportTo[part] = {};
                objToExportTo = objToExportTo[part];
            }
        }
    }
}
导出函数unfuscateSymbol(publicPath、object、objectToExportTo=window){
//同样的代码可以编译也可以不编译,所以只有在混淆的情况下才可以不混淆
if(unobfuscateSymbol.name!==“unobfuscateSymbol”){
const/**Array*/parts=publicPath.split('.');
让/**Object*/objToExportTo=objectToExportTo;
let/**字符串*/部分;
const/**number*/nbOfParts=零件长度;
对于(让/**number*/i=0;i
我是如何详细识别问题的:

  • 为了理解导出问题,在浏览器中加载HTML测试页面时,我尝试在闭包库中定义的exportSymbol函数中放置断点:no break

  • 我通过添加一个console.log(“我的库正在执行”):我能够在
    goog.require
    /
    goog.provide
    版本的我的库中看到消息,但在es6
    导入
    /
    导出
    版本中看不到。当然,如果不执行,就不会导出任何符号

  • 我用生命来包装我的图书馆。闭包编译器参数:
    --output_wrapper“(function(){%output%})()”
    ,浏览器控制台中出现了我的库中的执行错误消息。我发现,
    goog.global
    ,闭包库的基本名称空间,在中断时是
    未定义的

  • 我将闭包库移到要编译的文件堆栈之前。闭包编译器参数:
    –js Closure lib path/base.js–js myfile1.js–js myfile2.js…
    以确保编译的
    goog
    内容在第一次
    导出之前