Haxe for javascript 没有全局命名空间污染?
此问题仅适用于 Haxe 版本 2.10
我知道haxe有一段时间了,但直到昨天才真正使用过它。出于好奇,我决定移植 showdown.js,这是 markdown.pl,到 haxe。这非常简单,并且它生成的 javascript 似乎运行良好(编辑:如果您想查看它的实际效果,请查看此处)。
但是,我注意到生成的代码在全局命名空间中转储了大量内容...更糟糕的是,它通过将值分配给未声明的标识符来实现,而不使用var
关键字,因此即使您用闭包包装整个事物,它们也是全局的。
例如...
if(typeof js=='undefined') js = {}
...
Hash = function(p) { if( p === $_ ) return; {
...
EReg = function(r,opt) { if( r === $_ ) return; {
...
我设法用 sed 清理了大部分内容,但我也被这样的东西困扰:
{
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);
}
}
这是一些非常令人讨厌的 javascript。
问题
是否有 haxe 的分叉或克隆不会污染全局?是否值得修改 haxe 源来获得我想要的东西,或者有人已经解决了这个问题?谷歌搜索并没有出现太多结果。我愿意接受任何建议。同时,我很想知道这个东西会生成什么样的 PHP 代码...:D
答案吗?
以下是我尝试过的一些想法:
后处理
这是我简陋的构建脚本;它在剥离内容方面做得很好,但它并不能捕获所有内容。我犹豫是否要删除对内置构造函数原型的修改;我确信那会破坏一切。修复所有问题可能是一项艰巨的任务,如果有人已经完成了工作,我不想开始它...
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 开关拯救了这一天
感谢 Dean Burge指出命名空间开关。这几乎解决了我的问题,并提供了一点帮助。这是我当前的构建脚本。我认为这捕获了所有全局变量......
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/compiler.jar --js markdown.clean.js \
--compilation_level SIMPLE_OPTIMIZATIONS \
> markdown.cc.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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我使用编译器上的命名空间开关来清理这些全局根类型。
I use the namespace switch on the compiler to clean those global root types up.
Haxe 不适合用于在 javascript Web 应用程序中编写独立的可重用组件。编译器为每个该死的编译生成标准库这一事实证明了这一点。 javascript 目标的最佳使用是完全用 haxe 编写应用程序并使用非类型化块调用外部内容,希望它不会破坏任何内容。您应该将 haxe 输出视为 Flash 剪辑,忽略它运行的环境,并假设它是唯一运行的东西。
或者您可以尝试使用 with() 块包装代码。
Haxe is not meant to be used for writing an isolated reusable component in a javascript web application. This is evidenced by the fact that the compiler emits standard library for every goddamn compilation. 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.
这里有一个命名空间(实验性)haxe 编译器 http://github.com/webr3/haxe
there's a namespaced (experimental) haxe compiler here http://github.com/webr3/haxe
JSTM JavaScript 生成器宏以多种方式优化 haxe 输出:
请查看 http:// /code.google.com/p/jstm/ 了解更多信息。
The JSTM JavaScript generator macro optimizes haxe output in a number of ways:
check out http://code.google.com/p/jstm/ for more info.