This question pertains to Haxe versions prior to 2.10
While I've been aware of Haxe for some time, I only recently began experimenting with it. Out of curiosity, I decided to port showdown.js, which is a JavaScript adaptation of markdown.pl, to Haxe. The process was fairly simple, and the generated JavaScript code seems to function correctly (edit: To see it in action, visit here).
However, I observed that the resulting code pollutes the global namespace significantly... and even worse, it does so by assigning values to undeclared identifiers without utilizing the var
keyword, making them global even within a closure.
For instance...
if(typeof js=='undefined') js = {}
...
Hash = function(p) { if( p === $_ ) return; {
...
EReg = function(r,opt) { if( r === $_ ) return; {
...
I managed to tidy up most of this using sed, but I'm also troubled by things like this:
{
String.prototype.__class__ = String;
String.__name__ = ["String"];
Array.prototype.__class__ = Array;
Array.__name__ = ["Array"];
Int = { __name__ : ["Int"]}
Dynamic = { __name__ : ["Dynamic"]}
Float = Number;
Float.__name__ = ["Float"];
Bool = { __ename__ : ["Bool"]}
Class = { __name__ : ["Class"]}
Enum = { }
Void = { __ename__ : ["Void"]}
}
{
Math.__name__ = ["Math"];
Math.NaN = Number["NaN"];
Math.NEGATIVE_INFINITY = Number["NEGATIVE_INFINITY"];
Math.POSITIVE_INFINITY = Number["POSITIVE_INFINITY"];
Math.isFinite = function(i) {
return isFinite(i);
}
Math.isNaN = function(i) {
return isNaN(i);
}
}
This JavaScript appears quite messy.
Queries
Is there a modified version or clone of Haxe available that doesn't introduce global contamination? Should I consider altering the Haxe source code to achieve my desired outcome, or has someone already addressed this issue? My attempts at researching have yielded minimal results. I am open to any suggestions. In the meantime, I am eager to witness the PHP code this tool will generate... :D
Solutions?
Below are some approaches I've experimented with:
Postprocessing
Here's my basic build script; it effectively removes redundant elements, though not all. I am cautious about removing modifications to default constructor prototypes as that could potentially cause issues. Rectifying everything might be quite a challenge, and I'd prefer not to commence unless the work has already been done...
haxe -cp ~/Projects/wmd-new -main Markdown -js markdown.js
echo "this.Markdown=(function(){ var \$closure, Float;" > markdown.clean.js;
sed "s/^if(typeof js=='undefined') js = {}$/if(typeof js=='undefined') var js = {};/g ;
s/^\([ \x09]*\)\([\$_a-zA-Z0-9]* = \({\|function\)\)/\1var \2/g ;
/^[ \x09]*\(else \)\?null;$/d ;
" markdown.js >> markdown.clean.js
echo "return Markdown}());" >> markdown.clean.js;
java -jar closure/compiler.jar --js markdown.clean.js \
--compilation_level SIMPLE_OPTIMIZATIONS \
> markdown.cc.js
--js-namespace switch saves the day
Credits to Dean Burge for suggesting the namespace switch. This essentially resolved my dilemma, with minor assistance. Here's my current build script. I believe this captures all global variables...
NS=N\$
haxe -cp ~/Projects/wmd-new -main Markdown --js-namespace $NS -js markdown.js
# export our function and declare some vars
echo "this.markdown=(function(){var \$_,\$Main,\$closure,\$estr,js,"$NS"" > markdown.clean.js;
# strip silly lines containing "null;" or "else null;"
sed "/^[ \x09]*\(else \)\?null;$/d ;" markdown.js >> markdown.clean.js
# finish the closure
echo "return "$NS".Markdown.makeHtml}());" >> markdown.clean.js;