Шаблон проекта Express.js

    Взять можно тут: github.com/maxatwork/expressjs_template (или в виде zip-архива).

    Что есть



    Установка

    Вытаскиваем zip-архив (чтоб ссылок на git не оставалось), разворачиваем в нужную папку, переходим в нее, выполняем npm install.

    Также, хорошо бы иметь установленными:
    # grunt - аналог make 
    npm install -g grunt
    
    # nodemon - запускает и перезапускает nodejs при изменении скриптов
    npm install -g nodemon
    


    Далее можно выполнить:
    • grunt — прогонит тесты
    • grunt watch — будет смотреть за изменениями файлов, и перезапускать тесты
    • nodemon app.coffee — запустит сервер


    Ну и неплохо бы поправить README.md и package.json под свои данные.

    Возможно, кому-то сэкономит 15 минут времени =)
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 17

      0
      Express староватый выбрали, ну и забыли упоминуть jade который у вас в качестве template engine.
      А вот за nodemon спасибо, я как-то и не знал.
        0
        jade вроде идёт в экспрессе по умолчанию. Есть нюансы?
          +1
          Нет, вы немного ошибаетесь. Jade хоть и написан тем же автором по нику visionmedia, но является отдельным проектом. Собственно строчки:

          app.configure ->
              app.set "views", "#{__dirname}/views"
              app.set 'view engine', 'jade'
          

          и устанавливают jade как template engine по-умолчанию в express, без них работать не будет. Если мне не изменяет память, а она у меня такая, то если ничего не указывать, то мы получим ejs
            0
            Ок, спасибо.
          0
          Оу, и точно! package.json взял из стпрого проекта, и на версию внимания не обратил.
            0
            и jade добавил в описание, да.
            0
            А jade лучше чем haml, или это кому как нравится?
              +1
              Они близки очень (собственно, автор и не скрывает источника вдохновения), но Jade мне показался чище, что-ли (не рябит в глазах от знаков процента хотя-бы).
                0
                Jade приятнее, однозначно. Вообще, все круто, чисто, красиво и минималистично.

                Но он, собака, самый медленный из всех возможных альтернатив.
                Dust.js и Handlebars.js — значительно быстрее. Про DoT.js вообще молчу, хотя у него не самый приятный синтаксис (впрочем, хотя бы нет знаков %, что уже хорошо).

                Где-то было даже сравнение производительности. Если что — да, я понимаю, что для кого-то «преждевременная оптимизация...» и все такое, но все-таки это немаловажно. Баланс между красотой и производительностью.
                  0
                  А, вот отчет сравнения на небольших шаблонах на JSPerf.
                    0
                    Мне jade нравится тем, что:

                    • есть нормально реализованное наследование шаблонов (чего, кстати, нет в haml'е)
                    • стиль кода близок к coffeescript


                    Вопрос же производительности шаблонизатора так остро не стоял.

                    В конце концов, если будет надо — думаю, не будет большим вопросом сконвертировать шаблоны из одного формата в другой, а в процессе разработки и сопровождения jade точно удобнее doT.js и прочего подобного (банально читать легче).
                      0
                      Тут я не спорю, в плане синтаксиса Jade прекрасен! Особенно, если учесть, что я тоже предпочитаю CoffeeScript где это возможно. Для небольшого проекта это не так критично, а вот для высоких нагрузок — вполне.

                      Недавно использовали Node.js не только как REST/JSON/socket-сервисы, но и для формирования некоторых кусочков веб-страниц. И начинает душить жаба, когда понимаешь, что на рендеринг отдается столько времени с Jade (а особенно с «with»), когда «можно и по-другому» :)
                      +1
                      Производительность doT притянута за уши слухами. doT по умолчанию не экранирует данные, в отличие от всех своих «конкурентов». Вот и весь секрет. Экранирование данных это самая сложная операция в JS-шаблонизаторах, которая легко может увеличить время в бенчмарках раз в 5-10.

                      Я попытался сделать бенчмарк, который показывает более объективные результаты. В нём отдельно сравнивается скорость работы с экранированием данных и без, для каждого шаблонизатора, и уже сумма результатов берётся для сравнения, т.к. на деле экранирование дынных при генерации html применяется не редко. Также в параметры передаётся кусок текста нормального размера, который можно ожидать в боевом окружении. Он также серьёзно влияет на результаты. Сравнивать на нескольких коротких строчках — некорректно. И doT в данном случае уже далеко не лидер.

                      Без экранирования, он немного выигрывает у моего шаблонизатора ECT, т.к. doT имеет довольно ограниченный функционал. ECT содержит в себе систему загрузки шаблона с диска, кеширования и реализацию наследования и инъекций в шаблонах. Это требует некоторых операций, поэтому тут он немного проседает в попугаях. Но дело в том, что эти вещи понадобятся в любом случае, с любым шаблонизатором, если проект не hello world. И нам придётся дописывать их в приложении.

                        0
                        Ну для задач, где экранирование не требуется — не особо то и притянута. Он правда мега-быстр.

                        Но, согласен, честно было бы сразу сообщить о том, что doT.js далеко не так функционален как Jade и про экранирование. Но скорость Jade понятна — у него необычный и сложный для парсинга синтаксис. Но когда нужна была скорость и функциональность — Handlebars и Dust. Последний отлично работает с экранированием, поэтому и является одним из самых предпочтительных на текущий момент. doT — только для «особых случаев».

                        Спасибо за ссылку на ECT — обязательно посмотрим.
                          +1
                          Конечная скорость шаблонизатора не должна зависеть от синтаксиса шаблонов, т.к. все шаблонизаторы превращают шаблон в JS-функцию и далее выполняется эта функция. В моём бенчмарке скорость парсинга вообще не учитывается. Она совершенно не важна, т.к. компиляция происходит только 1 раз при первом считывании шаблона, далее выполняется уже скомпилированная функция. Скомпилированная функция в общем случае — простая конкатенация строк. Некоторые шаблонизаторы выполняют дополнительные действия внутри этой функции и просаживаются по производительности.

                          Вот некоторые примеры:

                          1. Использование with внутри функции. Так по умолчанию делают Jade и EJS. Этот оператор очень медленный, он просаживает данные шаблонизаторы по производительности в несколько раз. Используется для того чтобы можно было обращаться к переменным шаблона без префикса. Т.е. вместо locals.someVar или this.someVar писать просто someVar.

                          2. Отслеживание текущей позиции в файле для сохранения возможностей дебага. В этом случае перед каждой операцией внутри шаблона, в некоторую переменную сохраняется строка, на которой мы находимся в данный момент. Если во время выполнения шаблона произошла ошибка, мы сможем узнать строку на которой находится вызов плохой функции и исправить её. В большом шаблоне doT это будет сделать довольно непросто.

                          3. Обработка неопределённых переменных. Шаблон может содержать переменные, которые не будут определены в переданных ему данных. Если никак их не обрабатывать, то после преобразования в строку мы получим «undefined» на месте, где должна быть выведена переменная. А в случае с шаблонизаторами, которые используют with это прекратит работу с ошибкой обращения к неопределённой переменной. В контексте шаблонизатора, я считаю правильным замену неопредлённой переменной на пустую строку. Тогда в результирующем html на этом месте будет пустота. Можно, конечно, в коде шаблона писать что-то вроде locals.someVar || '', но во первых это сильно раздует код, во вторых обязательно где-нибудь всплывёт ошибка, что не вывелся 0, переданный в качестве параметра, т.к. он привёлся к False в условии. ECT сам умеет правильно работать с неопределёнными переменными, поэтому немного проигрывает по производительности doT на не экранированных данных.
                            0
                            Спасибо за подробности.

                            > «Конечная скорость шаблонизатора не должна зависеть от синтаксиса шаблонов, т.к. все шаблонизаторы превращают шаблон в JS-функцию и далее выполняется эта функция»

                            Полностью согласен с этим. То, что я имел в виду — синтаксис все-таки может определять то, какая именно функция генерируется и какие проверки содержит. И в Jade все менее очевидно, и необходимо больше проверок внутри уже сгенерированной функции.

                            Впрочем, может я ошибаюсь, и их возможно сделать полностью независимыми не только в теории. Однако тогда не совсем понятна чрезмерная неторопливость Jade — даже без «with».

                            Почему не может быть специального режима, в который можно компилировать шаблоны, после того как все отлажено и работает. Убрать лишние обработчики ошибок, прочие тяжеловесные проверки.

                            Вопрос как продвинутому в теме спецу — чем вызвана такая разница в runtime-производительности разных шаблонизаторов? Не по вышеперечисленным трем пунктам, а в целом? Почему так отличаются сгенерированные функции при схожей функциональности шаблонизатора? И, кстати, насколько влияет на это отдельно третий пункт (про неопределенные данные)?
                              0
                              По большому счёту проверки на наличие данных и сохранение информации о текущей строке не оказывают серьёзного влияния на производительность. Я их привёл выше как пример того, что может ещё делать функция шаблона.

                              Извиняюсь, что не очень понятно выразился в последнем предложении. Я немного сбился с мысли. Я имел ввиду что ECT проседает относительно doT из-за всех дополнительных возможностей, которые включены в него, а не только из-за проверки данных. Кеширование, наследование, инъекции понадобятся в любом случае в более-менее большом проекте и данный разрыв нивелируется за счёт написания собственных реализаций недостающего функционала на уровне приложения.

                              Относительно различия производительности схожих по функциональности шаблонизаторов — тут идут в ход микрооптимизации. Тут надо понимать, что соревнуемся мы с операцией конкатенации строки, которая очень быстрая. В такой ситуации любая лишняя операция может погубить всё.

                              Грубый пример:

                              var i = '1' + '2' + '3';
                              

                              намного быстрее чем

                              var i = '1';
                              i += '2';
                              i += '3';
                              

                              Во время разработки ECT я тестировал множество возможных вариантов написания одного и того же кода с помощью микробенчмарков и выбирал самые быстрые. К сожалению это пока единственный вариант написания экстремально быстрого кода на JS (если не считать знание наизусть всей кухни ECMAScript и V8).

                              Выглядит это примерно так:

                              function bench (fn) {
                                      var t1 = Date.now();
                                      for (var i = 0; i < 10000000; i++) {
                                              fn();
                                      }
                                      var t2 = Date.now();
                                      console.log(t2 - t1);
                              }
                              
                              var fn1 = function() {
                                      var i = '1' + '2' + '3';
                              }
                              
                              var fn2 = function() {
                                      var i = '1';
                                      i += '2';
                                      i += '3';
                              }
                              
                              bench(fn1);
                              bench(fn2);
                              

                  Only users with full accounts can post comments. Log in, please.