No Exported Symbols With Es6 Modules Library Compiled By Closure Compiler
Solution 1:
After further investigations, I found the solution.
Although loaded in the browser without any error in the console (except undefined whatever
of course), my library was not executed. I simply moved the closure library ahead of the file stack to be compiled and my library was then properly executed by the browser with my symbols properly exported. See below for more details.
The 3 ways to export symbols are working in compiled es6 modules: /** @export */ whatever
, goog.exportSymbol('whatever', whatever)
, window['whatever'] = whatever
. The first 2 being a handy way for the third one (for root symbols).
Nevertheless /** @export */ myClass
generates an unfriendly unobfuscated names like myClass$$module$source-filename-with-path
.
To get the unobfuscated name myClass
, avoid a goog
function within my code and enable neatly both compiled/uncompiled mode, I removed the /** @export */
and add unobfuscateSymbol('myClass', myClass)
after class myClass { ... }
. It's my "own" function directly inspired from exportSymbol
function defined in the closure library. This is only required for root symbols like classes, you can keep /** @export */
for all the symbols (properties, functions etc.) defined in the class.
Here is the source code:
export function unobfuscateSymbol(publicPath, object, objectToExportTo = window) {
// Same code can be used compiled and not compiled so unobfuscation only in case of obfuscationif (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;
} elseif (objectToExportTo[part] && objectToExportTo[part] !== Object.prototype[part]) {
objToExportTo = objectToExportTo[part];
} else {
objToExportTo[part] = {};
objToExportTo = objToExportTo[part];
}
}
}
}
How I identified the issue in details:
To understand the export issue, I tried to put a breakpoint in the exportSymbol function defined in the closure library while loading my HTML test page in the browser: no break...
I double checked this execution issue by adding a console.log("my library is being executed"): I was able to see the message in the
goog.require
/goog.provide
version of my library but not in the es6import
/export
version. Without execution, of course, no symbol exported.I wrapped my library with a IIFE. Closure compiler argument:
--output_wrapper "(function(){%output%})()"
and an execution error message in my library appeared in the browser console. I discovered thatgoog.global
, the base namespace for the Closure library, wasundefined
at the break time.I moved the closure library ahead of the file stack to be compiled. Closure compiler arguments:
–js closure-lib-path/base.js –js myfile1.js –js myfile2.js …
to make sure compiledgoog
stuff is before the firstexportSymbol
call generated by the first/** @export */
compiled.Execution and exports were OK then in the browser. I just added the
unobfuscateSymbol
function as described above to get the same friendly exported names as for thegoog.require
/goog.provide
version of my library.
Post a Comment for "No Exported Symbols With Es6 Modules Library Compiled By Closure Compiler"