Haxe для javascript без глобального загрязнения пространства имен?

Этот вопрос относится только к версии Haxe ‹ 2.10

Я знал о haxe некоторое время, но никогда не играл с ним до вчерашнего дня. Из любопытства я решил портировать showdown.js, javascript-порт markdown.pl, чтобы удалить. Это было довольно просто, и генерируемый им javascript, кажется, работает нормально (редактировать: Если вы хотите увидеть его в действии, проверьте его здесь).

Однако я заметил, что сгенерированный код сбрасывает массу информации в глобальное пространство имен... и, что еще хуже, он делает это, присваивая значения необъявленным идентификаторам без использования ключевого слова var, поэтому они global, даже если вы оберните все это закрытием.

Например...

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 спасает положение

Спасибо Дину Берджу за указание на переключатель пространства имен. Это в значительной степени решило мою проблему с небольшой помощью. Вот мой текущий скрипт сборки. Я думаю, что это захватывает все глобальные переменные...

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;

person Dagg Nabbit    schedule 30.09.2010    source источник
comment
Этот вопрос больше не актуален, так как haxe 2.10. попробуйте try.haxe.org/#1cf90   -  person César Alforde    schedule 18.07.2012
comment
@CésarAlforde Почему этот вопрос больше не актуален?   -  person Anderson Green    schedule 20.11.2012
comment
потому что, начиная с версии haxe 2.10, весь сгенерированный код заворачивается в анонимную функцию, поэтому глобальное пространство имен не загрязняется, это то же самое, что вы получаете из сценария coffeescript.   -  person César Alforde    schedule 20.11.2012


Ответы (4)


Я использую переключатель пространства имен в компиляторе, чтобы очистить эти глобальные корневые типы.

person Dean Burge    schedule 30.09.2010
comment
Это позаботилось о большинстве вещей, о которых я беспокоился. Есть еще несколько необъявленных глобальных переменных; Я нашел $_, $Main, $closure, $estr, js и определяемое пользователем пространство имен. Это можно легко исправить, объявив vars в начале замыкания, хотя - person Dagg Nabbit; 30.09.2010
comment
Я только что обнаружил, что кто-то сообщил об ошибке для этого: code.google.com. /p/haxe/issues/detail?id=214 - person Andy Li; 01.10.2010

Haxe не предназначен для написания изолированного многократно используемого компонента в веб-приложении javascript. Об этом свидетельствует тот факт, что компилятор выдает стандартную библиотеку для каждой чертовой компиляции. Наиболее оптимальное использование цели javascript - написать приложение полностью на haxe и вызывать внешние вещи, используя нетипизированные блоки, надеясь, что это ничего не сломает. Вы должны рассматривать вывод haxe как флэш-клип, не обращая внимания на среду, в которой он работает, предполагая, что это единственное, что работает.

Или вы можете попробовать обернуть код блоком with().

person artificialidiot    schedule 30.09.2010
comment
Спасибо за ответ. Если я не пишу изолированный повторно используемый компонент, я пишу мусор, насколько мне известно. Однако у меня все еще есть несколько идей. Кстати, я смеялся над этой штукой с блоком... Надеюсь, это была шутка :) - person Dagg Nabbit; 30.09.2010
comment
Кстати, у haxetacy есть пост-компилятор, который может разбивать классы на файлы: code.google. com/p/haxetacy/wiki/посткомпилятор - person Andy Li; 30.09.2010
comment
Я не хочу разбивать их на файлы, я просто хочу избежать каких-либо глобальных переменных, которые я специально не экспортировал. - person Dagg Nabbit; 30.09.2010

здесь есть компилятор haxe с пространством имен (экспериментальный) http://github.com/webr3/haxe

person blackdog66    schedule 30.09.2010
comment
Быстро просмотрел, но я не уверен, что это то, что мне нужно... Спасибо. - person Dagg Nabbit; 30.09.2010

Макрос генератора JSTM JavaScript оптимизирует вывод haxe несколькими способами:

  1. вывод javascript разбивается на отдельные файлы для каждого типа
  2. эти файлы оптимизированы
  3. скрипт загрузчика загружает необходимые типы асинхронно
  4. используется только одна глобальная переменная: jstm
  5. загружается только тот код, который действительно необходим для запуска вашего приложения.
  6. новые типы могут быть загружены во время выполнения, что делает возможным масштабирование приложений

посетите страницу http://code.google.com/p/jstm/ для получения дополнительной информации.

person Cref    schedule 24.11.2010