This question only applies to Haxe version < 2.10
I've known about haxe for a while, but never really played with it until yesterday. Being curious, I decided to port showdown.js, a javascript port of markdown.pl, to haxe. This was pretty straightforward, and the javascript it generates seems to run fine (edit: If you want to see it in action, check it out here).
However, I noticed that the generated code dumps a ton of stuff in the global namespace... and what's worse, it does it by assigning values to undeclared identifiers without using the var
keyword, so they're global even if you wrap the whole thing with a closure.
For example...
if(typeof js=='undefined') js = {}
...
Hash = function(p) { if( p === $_ ) return; {
...
EReg = function(r,opt) { if( r === $_ ) return; {
...
I managed to clean most of that up with sed, but I'm also bothered by stuff 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 is some pretty unsavory javascript.
Questions
Is there a fork or clone of haxe somewhere that doesn't pollute globals? Is it worth it to modify the haxe source to get what I want, or has someone already solved this? Googling hasn't turned up much. I'm open to any suggestions. Meanwhile, I'm dying to see what kind of PHP code this thing's going to produce... :D
Answers?
Here are some of the ideas I've tried:
postprocessing
Here's my humble build script; it does a pretty good job of stripping stuff out, but it doesn't catch everything. I'm hesitant to remove the modifications to the built-in constructor prototypes; I'm sure that would break things. Fixing everything might be a bit of a task, and I don't want to start on it if someone's already done the work...
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/piler.jar --js markdown.clean.js \
--pilation_level SIMPLE_OPTIMIZATIONS \
> markdown.js
--js-namespace switch saves the day
Thanks to Dean Burge for pointing out the namespace switch. This pretty much solved my problem, with a minor bit of help. Here's my current build script. I think this catches all the 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;
This question only applies to Haxe version < 2.10
I've known about haxe for a while, but never really played with it until yesterday. Being curious, I decided to port showdown.js, a javascript port of markdown.pl, to haxe. This was pretty straightforward, and the javascript it generates seems to run fine (edit: If you want to see it in action, check it out here).
However, I noticed that the generated code dumps a ton of stuff in the global namespace... and what's worse, it does it by assigning values to undeclared identifiers without using the var
keyword, so they're global even if you wrap the whole thing with a closure.
For example...
if(typeof js=='undefined') js = {}
...
Hash = function(p) { if( p === $_ ) return; {
...
EReg = function(r,opt) { if( r === $_ ) return; {
...
I managed to clean most of that up with sed, but I'm also bothered by stuff 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 is some pretty unsavory javascript.
Questions
Is there a fork or clone of haxe somewhere that doesn't pollute globals? Is it worth it to modify the haxe source to get what I want, or has someone already solved this? Googling hasn't turned up much. I'm open to any suggestions. Meanwhile, I'm dying to see what kind of PHP code this thing's going to produce... :D
Answers?
Here are some of the ideas I've tried:
postprocessing
Here's my humble build script; it does a pretty good job of stripping stuff out, but it doesn't catch everything. I'm hesitant to remove the modifications to the built-in constructor prototypes; I'm sure that would break things. Fixing everything might be a bit of a task, and I don't want to start on it if someone's already done the work...
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/piler.jar --js markdown.clean.js \
--pilation_level SIMPLE_OPTIMIZATIONS \
> markdown.js
--js-namespace switch saves the day
Thanks to Dean Burge for pointing out the namespace switch. This pretty much solved my problem, with a minor bit of help. Here's my current build script. I think this catches all the 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;
Share
Improve this question
edited Jul 18, 2012 at 0:05
César Alforde
2,1182 gold badges15 silver badges17 bronze badges
asked Sep 30, 2010 at 6:52
Dagg NabbitDagg Nabbit
76.8k19 gold badges114 silver badges141 bronze badges
3
- This question is no longer relevant since haxe 2.10. try try.haxe/#1cf90 – César Alforde Commented Jul 17, 2012 at 23:47
- @CésarAlforde Why is this question no longer relevant? – Anderson Green Commented Nov 20, 2012 at 1:09
- because since haxe 2.10 all the generated code is wrapped in an anonymous function, so there is not global namespace pollution, it's the same that you get from a coffeescript script. – César Alforde Commented Nov 20, 2012 at 2:55
4 Answers
Reset to default 7I use the namespace switch on the piler to clean those global root types up.
Haxe is not meant to be used for writing an isolated reusable ponent in a javascript web application. This is evidenced by the fact that the piler emits standard library for every goddamn pilation. Most optimal use of javascript target is to write an application entirely in haxe and call external stuff using untyped blocks hoping it won't break anything. You should treat haxe output like a flash clip, oblivious to the environment it runs in, assumes it is the only thing running.
Or you might try wrapping the code with a with() block.
there's a namespaced (experimental) haxe piler here http://github./webr3/haxe
The JSTM JavaScript generator macro optimizes haxe output in a number of ways:
- the javascript output is split into seperate files per type
- these files are optimized
- a loader script loads the required types asynchronously
- only one global variable is used: jstm
- only code that is actually required to run your app is downloaded
- new types can be loaded at runtime which makes possible highly scalable apps
check out http://code.google./p/jstm/ for more info.