Pull to refresh

Comments 27

Статья в руку.
Буквально на днях столкнулся с интереснейшей штукой, но ещё не успел её изучить:
github.com/gkz/grasp она позволяет писать запросы к JS-коду, с помощью которых можно делать замены итп. По сути на её основе можно запилить макросы, что я и собирался сделать. А Sweet прямо заточен под этот кейс.
Макросы (вообще в целом) тема весьма интересная.
Хорошая библиотека, но как обычно есть подводные камни.
Во первых,
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 в его текущем виде больше подходит, когда вам нужно сделать «по-быстрому» несколько синтаксических расширений под свой проект/библиотеку/фрэймворк.

Про отладку — надеюсь браузеры этому смогут научиться.
А можно реализовать ES6 стрелочные функции с помощью этой либы?
Да, вот пример. Это не полная реализация, например нехватает неявного return да и много чего другого, но это все реализуемо.
Круть, попробую допилить. Уж очень слово function достало.
Очень хорошо, не хватает кейсов с одним выражением, где можно опустить { и } и кейсов с одним аргументов где можно опустить ( и )
Потом можно отправить PR в es6-macros проект или зарелизить отдельным проектом на npm/github.
Зачем пользоваться неполноценной реализацией (да ещё и медленной) если можно воспользоваться транслятором и получить не только стрелочные функции, но и деструктуризацию, классы, дефолтные значения и много другое?
Плохо вы рекламу делаете. Ни кто же не мешает bind заменить на явный .call, но код будет раздуваться.
Очевидно же что каждый способ будет иметь свои преимущества и недостатки.
На какое выражение ваш транслятор заменит стрелочную функцию?
Там в папке tests всё есть. Вот например из первого теста стрелочных функций:
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
Ага, пасиб. Не заметил скопировав. Я хотел измерить только кол-во операции у явного способа.
У стрелочных функций очень много неявных моментов, я специально писал тесты, чтобы покрыть все возможные кейсы: 1, 2, 3, 4. Боюсь написать макрос, который будет проходить эти тесты довольно сложно.
Ну теперь хоть понятно, что вам в не понравилось. Но у вас в тестах не только лишь стрелочные функции. Я лично предпочел бы использовать макрос чисто для преобразования стрелок, а es6 можно и подождать.
Не думаю, что это будет сложно, макрос для деструктурирования уже есть отдельно в es6-macros — его можно переиспользовать, например. Для парсинга в sweet.js все равно используется esprima и es6 она должна парсить на отлично.
Пока библиотека еще очень бажная, косяки на каждом шагу, поэтому в разработке не особенно удобна.
Да и не все реализовать удастся. Типа for… in array не получится сделать.
Можно подробнее почему нелья for… in array? Баги есть, но довольно разработка довольно активна.
А как вы отличите от нативного for in? Иначе нет смысла делать — запоминать один синтаксис for in для массива, другой — для объекта.
А, ну это макросом эффективно не решится. Но для массивов/итераторов вроде есть for… of синтаксис.
Хороший оператор, жаль только что совсем экспериментальный )
Ну как экспериментальный — это часть ES6.
note that the syntax and behavior of an experimental technology is subject to change in future version of browsers as the spec changes.

Цитата с MDN. Пока все же некомфортно использовать операторы с таким предупреждением. Хотя кому как.
Но вообще неэффективное решение возможно, можно просто переопределить 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.

Articles