Javascript 闭包编译器编译es6模块库时没有导出符号
起点:闭包编译器(高级优化级别)在单个库文件中成功编译了许多js文件(无警告/错误) 在这些js文件中: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文件
和goog.require
用于在它们之间导入/导出东西goog.provide
用于库外所需的任何/**@export*/
(const/function/Class/var)前面
内容
我想要的:移动到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
内容在第一次导出之前