起点:Closure Compiler(ADVANCED_OPTIMIZATIONS级别)在单个库文件中成功编译了许多js文件(没有警告/错误)。
在这些js文件中:
ListView
和goog.require
用于导入/导出它们之间的内容goog.provide
在/** @export */
(const / function / Class / var)前面使用。某些HTML文件包含库和一些未编译的js成功访问此库中定义的所有whatever
。
我想要的:转到es6模块语法
我为每个js文件做了什么:
whatever
替换为goog.require
,其中包含Class,from另一个js文件的函数列表import
已删除,goog.provide
已添加到其他js文件所需的每个类,函数等前面export
都不需要更改/** @export */
。whatever
替换为/** @export */ whatever
这是成功编译的(没有警告/错误,仍处于ADVANCED_OPTIMIZATIONS级别)。
问题:现在,对于相同的HTML文件,浏览器会看到库中定义的所有goog.exportSymbol('whatever', whatever)
都是“未定义的”。实际上,当我在控制台中键入whatever
时,我可以看到编译器更改了所有符号名称(Object.keys( window )
,aa
,ba
等),但我没有导出符号ca
。
示例:whatever
是库中定义的demoVisitors
,需要在外部。
在库文件之前,我可以看到const array
,并且内容在HTML页面中正确显示。更改es6模块后,我可以看到... w("demoVisitors",[Oa,La,Ma,Na]); ...
(... H("demoVisitors$$module$filemane",Oa); ...
是其中filename
已定义的文件名)对于尝试1而demoVisitors
对于尝试2 H("demoVisitors",[Na,Ka,La,Ma]);
在同一页面的浏览器中未定义。
答案 0 :(得分:1)
经过进一步调查,我找到了解决方案。
虽然在浏览器中加载时没有任何错误(当然除了undefined whatever
),但是我的库没有被执行。我只是将闭包库移到要编译的文件堆栈之前,然后浏览器正确执行我的库,并正确导出我的符号。有关详细信息,请参见下文。
导出符号的3种方法在编译的es6模块中有效:/** @export */ whatever
,goog.exportSymbol('whatever', whatever)
,window['whatever'] = whatever
。前两个是第三个方便(根符号)。
尽管如此/** @export */ myClass
会产生一些不友好的未经混淆的名称,例如myClass$$module$source-filename-with-path
。
要获取未经模糊处理的名称myClass
,请避免在我的代码中使用goog
函数并巧妙地启用已编译/未编译模式,我删除/** @export */
并在{{1}之后添加unobfuscateSymbol('myClass', myClass)
}}。这是我的“自己的”函数,它直接受到闭包库中定义的class myClass { ... }
函数的启发。这只适用于像类这样的根符号,您可以为类中定义的所有符号(属性,函数等)保留exportSymbol
。
以下是源代码:
/** @export */
我如何详细确定问题:
为了理解导出问题,我尝试在闭包库中定义的exportSymbol函数中放置一个断点,同时在浏览器中加载我的HTML测试页面:没有中断......
我通过添加console.log(“我的库正在执行”)仔细检查了这个执行问题:我能够看到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];
}
}
}
}
/ goog.require
版本中的消息我的库,但不在es6 goog.provide
/ import
版本中。当然,没有执行,没有符号导出。
我用IIFE包装了我的图书馆。 Closure编译器参数:export
和我的库中的执行错误消息出现在浏览器控制台中。我发现在休息时间{Cl}库的基本命名空间--output_wrapper "(function(){%output%})()"
是goog.global
。
我将闭包库移到要编译的文件堆栈之前。关闭编译器参数:undefined
以确保编译的–js closure-lib-path/base.js –js myfile1.js –js myfile2.js …
内容在第一个goog
编译生成的exportSymbol
调用之前。
然后在浏览器中执行和导出就可以了。我刚刚添加了/** @export */
函数,如上所述,以获得与我的库的unobfuscateSymbol
/ goog.require
版本相同的友好导出名称。