Comments 27
Статья в руку.
Буквально на днях столкнулся с интереснейшей штукой, но ещё не успел её изучить:
github.com/gkz/grasp она позволяет писать запросы к JS-коду, с помощью которых можно делать замены итп. По сути на её основе можно запилить макросы, что я и собирался сделать. А Sweet прямо заточен под этот кейс.
Макросы (вообще в целом) тема весьма интересная.
Буквально на днях столкнулся с интереснейшей штукой, но ещё не успел её изучить:
github.com/gkz/grasp она позволяет писать запросы к JS-коду, с помощью которых можно делать замены итп. По сути на её основе можно запилить макросы, что я и собирался сделать. А Sweet прямо заточен под этот кейс.
Макросы (вообще в целом) тема весьма интересная.
Хорошая библиотека, но как обычно есть подводные камни.
Во первых,
Проблема вся в том, что ни один браузер с поддержкой Source Map не умеет (на данный момент) производить обратное переименовывание переименованных переменных. Т.е. при отладки, если я вижу переменную «x» в коде, то я не смогу посмотреть её значение ни наведя на неё мышку, ни в консоли введя "> x", ни в инспекторе областей видимости — эта переменная будет переименована в что-то типа «x123».
Во вторых, не советую ей пользоваться для трансляции es6 в es5. Лучше воспользоваться «честным» транслятором.
Например, вот подобные правила:
реализуют очень примитивную поддержку шаблонов деструктуризации. Не находил ещё макросов для Sweet.js которые нормально бы реализовывали трансляцию es6.
Во первых,
UPDATE. Забыл сказать, что Sweet.js имеет возможность генерации карт кода (source maps), поэтому сложностей с отладкой (по крайней мере в браузере) быть не должно.
Проблема вся в том, что ни один браузер с поддержкой Source Map не умеет (на данный момент) производить обратное переименовывание переименованных переменных. Т.е. при отладки, если я вижу переменную «x» в коде, то я не смогу посмотреть её значение ни наведя на неё мышку, ни в консоли введя "> x", ни в инспекторе областей видимости — эта переменная будет переименована в что-то типа «x123».
Во вторых, не советую ей пользоваться для трансляции es6 в es5. Лучше воспользоваться «честным» транслятором.
Например, вот подобные правила:
// Array destructuring
case [...front, back] => back.concat(front)
// Object destructuring
case { foo: 'bar', x, 'y' } => x
реализуют очень примитивную поддержку шаблонов деструктуризации. Не находил ещё макросов для Sweet.js которые нормально бы реализовывали трансляцию es6.
Для ES6-to-ES5, согласен, что лучше использовать отдельные трансляторы, которые, к тому же, и работают быстрее. Sweet.js в его текущем виде больше подходит, когда вам нужно сделать «по-быстрому» несколько синтаксических расширений под свой проект/библиотеку/фрэймворк.
Про отладку — надеюсь браузеры этому смогут научиться.
Про отладку — надеюсь браузеры этому смогут научиться.
Очень уж наркоманский синтаксис у нее. Есть, имхо, более простое решение: www.nongnu.org/espresso/js-cpp.html
А можно реализовать ES6 стрелочные функции с помощью этой либы?
Круть, попробую допилить. Уж очень слово function достало.
Пока вот что получилось. Выглядит вроде правдоподобно.
Очень хорошо, не хватает кейсов с одним выражением, где можно опустить { и } и кейсов с одним аргументов где можно опустить ( и )
Потом можно отправить PR в es6-macros проект или зарелизить отдельным проектом на npm/github.
Зачем пользоваться неполноценной реализацией (да ещё и медленной) если можно воспользоваться транслятором и получить не только стрелочные функции, но и деструктуризацию, классы, дефолтные значения и много другое?
Плохо вы рекламу делаете. Ни кто же не мешает bind заменить на явный .call, но код будет раздуваться.
Очевидно же что каждый способ будет иметь свои преимущества и недостатки.
На какое выражение ваш транслятор заменит стрелочную функцию?
Очевидно же что каждый способ будет иметь свои преимущества и недостатки.
На какое выражение ваш транслятор заменит стрелочную функцию?
Там в папке tests всё есть. Вот например из первого теста стрелочных функций:
es6:
es5:
es6:
{
let test = 987;
var result = (function() {
var this$0 = this;
var obj = {
test: 123
, arr: () => () => this.test + test
};
function innerTest() {
console.log(this$0.test === "testString");
}
innerTest();
return obj.arr()();
}).call({test: "testString"});
}
es5:
{
var test$0 = 987;
var result = (function() {var this$1 = this;
var this$0 = this;
var obj = {
test: 123
, arr: function() {return function() {return this$1.test + test$0}}
};
function innerTest() {
console.log(this$0.test === "testString");
}
innerTest();
return obj.arr()();
}).call({test: "testString"});
}
Еще, у вас в тесте ( явный .call ) ошибка. Вы, я уверен непреднамеренно, изменили тест «scope», чтобы он явно проигрывал. Вот я сделал правильную версию теста: jsperf.com/bind/5
Ну теперь хоть понятно, что вам в не понравилось. Но у вас в тестах не только лишь стрелочные функции. Я лично предпочел бы использовать макрос чисто для преобразования стрелок, а es6 можно и подождать.
Не думаю, что это будет сложно, макрос для деструктурирования уже есть отдельно в es6-macros — его можно переиспользовать, например. Для парсинга в sweet.js все равно используется esprima и es6 она должна парсить на отлично.
Пока библиотека еще очень бажная, косяки на каждом шагу, поэтому в разработке не особенно удобна.
Да и не все реализовать удастся. Типа for… in array не получится сделать.
Да и не все реализовать удастся. Типа for… in array не получится сделать.
Можно подробнее почему нелья for… in array? Баги есть, но довольно разработка довольно активна.
А как вы отличите от нативного for in? Иначе нет смысла делать — запоминать один синтаксис for in для массива, другой — для объекта.
Ok, набросал маленький DSL для написания express приложений
var app = express {
get "/path" {
header "Content-Type", "application/json"
write "hello"
write "more data"
end
}
post "/x" {
send 404, "not found"
}
}
Sign up to leave a comment.
Sweet.js: Синтаксические расширения для JavaScript