illumium.org

Главная › Блоги › Блог kayo

JavaScript: Node.JS, RequireJS, NodeLint и другие

kayo — Сб, 02/04/2011 - 15:47

Сегодня мы будем сносить себе бошку серверным и не только JS-ом. Скажу по секрету, Kayo с недавних пор подсел на NodeJS. Это штука, которая исполняет ваши мечты, оформленные согласно спецификации ECMAScript выполняет ваши коды, написанные на языке JavaScript вне среды браузера. NodeJS использует движок V8, и имеет набор библиотек, позволяющих писать полноценные программы. В частности мы можем разработать свой сервер web-приложений.

Вместо введения

Постараюсь сразу затуманить вам мозги всякой ненужной ерундой некоторыми полезными рассуждениями. Стиль написания серверных JavaScript-ов для NodeJS несколько отличается от скриптов для браузера.

Сложные приложения обычно состоят из нескольких файлов с кодом, которые на стороне клиента подключаются к станице. Обычно подключение происходит статически, и чтобы инициировать работу приложения нам необходимо позаботиться о том, чтобы к этому моменту все необходимые компоненты кода и данных были уже загружены. На стороне сервера в NodeJS для подключения скриптов используется commonjs подход. Скрипты подключают другие скрипты-модули вызовом require, подключаемые модули используют мета-переменную exports для того, чтобы сделать доступными объявления внутри себя другим скриптам.

Это обстоятельство осложняет написание универсальных модулей, которые могли бы работать как на стороне клиента, так и на сервере. Однако существуют решения, позволяющие несколько поправить положение. Одно из них RequireJS.

Другая проблема, с которой каждый разработчик на JavaScript обязательно сталкивается, связана с разными реализациями сред его исполнения. Хотя стандарт ECMAScript есть, однако далеко не все клиентские программы ему всецело следуют.

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

На этом пока хватит слов, пора показать, как это работает.

Вместо основной части

NodeJS

Проект достаточно динамично развивается, поэтому лучше взять версию поновее. На момент написания статьи у автора стояла версия 0.4.3 из ppa:chris-lea/node.js. Также нам пригодится npm, можно также поставить из ppa, если вы также сторонники чистоты и порядка в системе (у меня, кажется от сюда ppa:richarvey/nodester).

RequireJS

Библиотека использует единый способ объявления и подключения модулей — асинхронный. Выглядит это примерно нижеследующим образом.

Объявление модуля:

define(['требуемый_молуль_один', 'требуемый_модуль_два'],
function(импорт_модуля_один, импорт_модуля_два){
  // код модуля
  return экспорт_модуля;
});

Краткое объявление (у модуля отсутствуют зависимости):

define(function(){
  // код модуля
  return экспорт_модуля;
});

Ещё более краткое объявление:

define(
  //экспорт_модуля
);

Модули, указанные как требуемые в объявлении, подключаются автоматически, а функция инициализации модуля выполняется, когда все зависимости уже загружены.

Мы можем явно подключить модуль, например, нам это потребуется в main-модуле приложения. Делается это аналогично объявлению, с тем лишь исключением, что функция обратного вызова после удовлетворения всех зависимостей выполняется:

require(['требуемый_молуль_один', 'требуемый_модуль_два'],
function(импорт_модуля_один, импорт_модуля_два){
  // основной код программы
});

Берём RequireJS и находим файл r.js, он потребуется для связывания модулей в среде NodeJS. Чтобы нода начала понимать вызовы define и require «правильно», то есть в стиле RequireJS, нам потребуется указывать r.js при запуске приложения перед основным скриптом.

Для работы в клиенте нам потребуется лишь подключить скрипт require.js в коде страницы и указать ему файл запуска приложения:

<script data-main="myapp/main" src="myapp/require.js"></script>

JSLint

Теперь займёмся проверкой нашего быдло-кода на JS. Сразу скажу, инструментов существует несколько. Можно попробовать использующие носорога (rhino) и паукообразную обезьяну (spider monkey), но мне показалось, что лучше что-то поближе к ноде и желательно клиент-серверное для мгноверной проверки так сказать не отходя от пульта. Мне попался lintnode и сразу же понравился, правда без доработки напильником не обошлось, но это кхм… нормально.

Ставим инстумент npm-ом или берём из дерева git. Поскольку автор использует в качестве среды разработки атомный бронепоезд вся настройка будет описана для него. В Emacs есть минорный мод flymake, который реализует проверку кода налету, существенно увеселяя работу кодера улучшая процесс написания кода. Разработчик lintnode тоже приложил файл поддержки flymake.

Первое, что потребовалось сделать, после того, как lintnode был поставлен npm-ом, это добавить очередной мусор некоторые команды в ~/.emacs:

(setq lintnode-location "/usr/lib/node/lintnode")
(setq lintnode-port 3003)
(setq lintnode-node-program "nodejs")
(add-to-list 'load-path lintnode-location)
(require 'flymake-jslint)
(defun lintnode-service-started ()
  (ignore-errors
    (with-temp-buffer
      (open-network-stream "test lintnode server" (current-buffer)
			   "localhost" (number-to-string lintnode-port))
      t)))
(add-hook 'espresso-mode-hook
	  (lambda ()
	    (message "lintnode start")
	    (unless (lintnode-service-started)
	      (lintnode-start)
	      (while (not (lintnode-service-started))))
	    (flymake-mode t)
	    ))

Место положения lintnode и порт сервера могут у вас отличаться, но суть будет та же. При инициализации espresso-mode, мы запускаем сервер, если он ещё не запущен. У автора lintnode сервер запускается вручную командой lintnode-start, мы же несколько автоматизировали этот процесс.

Когда попробовал работу этой штуки в первый раз, немного расстроился, ибо почти весь мой код оказался совершенно негодным, невалидным. Однако что делать, програмить то надо, поэтому пришлось вооружиться консервным ножом и несколько понизить строгость проверки, а кроме того, научить его функциям типа define и require.

В файле /usr/lib/node/lintnode/app.js имеется объект jslint_options, его то нам и потребуется поправить:

var jslint_options = {
    bitwise: true,
    eqeqeq: true,
    immed: true,
    newcap: false, // хочу создавать объекты, прародители которых не начинаются с заглавной
    nomen: false, // хочу начинать названия переменных с _ $ и использовать другие грязные приёмы
    onevar: false, // хочу использовать не только один var в теле функций
    plusplus: true,
    regexp: true,
    rhino: true,
    undef: true,
    white: false, // не хочу обязательно ставить кучу пробелов между словами
    strict: false, // не будьте так строги
    predef: [ 'require', 'define' ] // запомните новые слова
};

В общем, теперь всё должно стать более-менее лояльно по отношению к нашим «волшебным» кодам, которые то и дело взрывают воздух перед монитором очередным эксепшном. Вот небольшой скриншот, показывающий, как примерно это работает:

flymake-mode в Emacs с lintnode

Вместо заключения

Прошу прощения за слишком свободный стиль изложения, использованный в статье, однако, тема такая, без кривой палки не заведёшь. Думаю, в ближайшее время напишу ещё несколько статей о JavaScript, о жизни и вообще. А в частности, на тему создания сервера web-приложений.

  • Разработка для WEB
  • javascript
  • jslint
  • nodejs
  • requirejs
  • Бортовой журнал Иллюмиума

Отправить комментарий

Содержимое этого поля является приватным и не будет отображаться публично.
  • Доступные HTML теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Syntax highlight code surrounded by the {syntaxhighlighter SPEC}...{/syntaxhighlighter} tags, where SPEC is a Syntaxhighlighter options string or "class="OPTIONS" title="the title".

Подробнее о форматировании

CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
                              __  __   _   _       
__ _ _ __ ___ __ _ | \/ | | | | | ____
/ _` | | '_ ` _ \ / _` | | |\/| | | |_| | |_ /
| (_| | | | | | | | | (_| | | | | | | _ | / /
\__, | |_| |_| |_| \__, | |_| |_| |_| |_| /___|
|_| |_|
Введите код, изображенный в стиле ASCII-арт.
RSS-материал

Навигация

  • Подшивки
  • Фотоальбомы

«Иллюмиум» на якоре.

Работает на Drupal, система с открытым исходным кодом.

(L) 2010, Illumium.Org. All rights reversed ^_~