I am aware that similar questions have been asked before, but methodology changes quickly so I'm seeking to understand current best practices. (In fact, as recently as 2 days ago, Chad Killingsworth added a comment to an accepted answer from three years ago that @expose
annotation is now deprecated.)
I'm using the module pattern. Working JSFIDDLE of the below code:
/** @const */
var MATHCALCS = (function () {
'use strict';
var MY = {};
/**
* @constructor
* @param {!Object} obj
* @expose
*/
MY.ModuleStruct = function (obj) {
/** @expose */
this.color = (obj.color !== undefined) ? obj.color : null;
/** @expose */
this.size = (obj.size !== undefined) ? obj.size : null;
};
/**
* @expose
*/
MY.ModuleStruct.prototype.clone = function () {
return new MY.ModuleStruct({
"color": this.color,
"size": this.size
});
};
MY.moduleProperty = 1;
/**
* @type {function(!Array<number>)}
* @expose
*/
MY.moduleMethod = function (a) {
var i, x = 0;
for (i = 0; i < a.length; i += 1) {
x = x + a[i];
}
return x;
};
return MY;
}());
window["MATHCALCS"] = MATHCALCS;*
Currently, using @expose
annotation, above can be minified with Closure in advance mode and the following calls work (minified example):
// call a public method
alert(MATHCALCS.moduleMethod([1, 2, 3]));
// allocate a new structure
var ms = new MATHCALCS.ModuleStruct({
"color": "red",
"size": "small"
});
alert(ms.color + '\t' + ms.size);
// clone a second instance
var ms2 = ms.clone();
alert(ms2.color + '\t' + ms2.size);
alert(ms !== ms2); // cloned objs are not equal
// and directly update the properties of the object
ms2.color = "white";
ms2.size = "large";
alert(ms2.color + '\t' + ms2.size);
If possible, without changing away from the module pattern, I would like to update code (approx 10,000 lines) to use @export
annotation. However, when I replace @expose
with @export
Closure raises this error:
ERROR - @export only applies to symbols/properties defined in the global scope.
Q: Is it possible, and if so, how should the above code be annotated to work with ADVANCED_OPTIMIZATIONS?
I am aware that I can possibly use this type of notation:
MY["ModuleStruct"] = MY.ModuleStruct;
MY["ModuleStruct"]["prototype"]["clone"] = MY.ModuleStruct.prototype.clone;
but exporting object properties this way will become tedious. Further JSLint complains about weird assignments so I would rather use JSDocs annotation.