0,0
рейтинг
31 мая 2013 в 16:55

Разработка → HTML/CSS/JS + Node.js + node-webkit = Кроссархитектурные приложения


С ростом популярности node.js он становится всё более привлекательным для разработки приложений. По крайней мере я в последнее время очень часто использую эту технологию для быстрой разработки оных. И на данный момент, технологически нет никаких препятствий для разработки кроссплатформенных приложений на одном языке. И не только классических Web-приложений (клиент-сервер) но и десктопных.

1. Если нужен быстрый старт, ставим express
npm install express

2. Создаём файл server.js примерно следующего содержания:
  var express = require('express');
  var http = require('http');
  var index = require('./routes/index.js');

  var app = express();
  // Куча всяких настроек express`а        
   
  app.get('/', index.index);

  http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
  });

3. Создаём файл index.js и кладём его в папку routes
exports.index = function(req, res){
  res.render('index', {});
};

4. Создаём index.ejs (я использую ejs как шаблонизатор) и кладём его в папку view
<!DOCTYPE html>
<html>
  <head>
      <meta charset="utf-8">
      <title>Hello world</title>
</head>
<body>
	<h1>Hello world!</>
</body>
</html>

Вуаля!

Запускаем
node server.js


Остаётся скопировать файлы на сервер, настроить nginx на проксирование запросов к нашему сервису… ну это Вы знаете. Но ведь не всегда есть желание или возможность возится с сервером. И даже если запускать проект локально… много возни. Хочется чего-нибудь «из коробки». Чтобы кликнул мышкой на ярлыке и приложение запустилось.

Проект node-webkit, анонсирование которого имеется на хабре, пригодится для сборки подобного.
Суть технологии в том, чтобы можно было внедрить api node.js в клиентский javascript-код. Т.е. вы можете соединяться с БД и файловой системой из клиентского кода напрямую, без посредников. Звучит заманчиво, и кстати работает, но мне не очень по душе такое смешение. Получается исключительно десктопное приложение. Мне по нраву другой вариант.
Приложение выполнено в классическом для web-приложений стиле: клиентский код и серверный. И я должен иметь возможность запускать его как на сервере, предоставляя многопользовательский доступ и как локальное (однопользовательское) приложение.

Вот рецепт:
1. node-webkit должен знать о стартовой html-странице которую он будет отображать первой.
дописываем в package.json следующее
"main": "nw-start.html"

2. nw-start.html будет следующего содержания
<!DOCTYPE html>
<html>
<head>
	<script>
		function bodyOnLoad(){
			require('./server.js');
			window.location.assign('http://localhost:3000/');
		}
	</script>
</head>
<body onload="bodyOnLoad()">
	<h1>
		Loading...
	</h1>	
</body>
</html>

3. Весь код server.js сделаем immediate-функцией.
(function startServer(){
    var express = require('express');
    var app = express();
    ....
    http.createServer(app).listen(app.get('port'), function(){
	  console.log('Express server listening on port ' + app.get('port'));
    });
})();

4. Упаковываем весь проект в zip-архив nw-project.zip
5. Запускаем
nw nw-project.zip


После недолгой паузы во время которой загружается «серверная» часть


Суть происходящего достаточно проста. node-webkit загружает стартовую страницу. После этого выполняется клиентская функция bodyOnLoad. bodyOnLoad загружает модуль server.js (вызов node.js require). Вызов приводит к исполнению кода в server.js и, следственно, запуску http-сервера. Осталось только сменить URL страницы, что и делает window.location.assign('http://localhost:3000/').

Подобный подход позволяет не меняя архитектуры web-приложения сделать его desktop-версию. Правда надо понимать, что за эту простоту придётся заплатить некоторой производительностью… ведь обмен данными будет происходить не напрямую, а через сетевые запросы.

Удачных выходных…
Андрей Громоздов @AndyGrom
карма
24,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Спецпроект

Самое читаемое Разработка

Комментарии (20)

  • 0
    А ещё есть Sencha Desktop Packager. Платная, зато не нужно городить огород с NodeJS, сетью и т.п. Для кроссплатформенной разработки вполне годится, имхо.
    • +2
      Статья на эту тему была бы уместна…
    • +6
      есть и просто node-webkit, без express, без сети, кросплатформенный и бесплатный
    • 0
      Сыроват этот Sencha Desktop Packager еще. Когда я последний раз его пробовал остановился на том, что у него нету поддержки history и наше веб приложение дальше первой страницы не куда не двигалось… Хотя может сейчас уже исправили, обещали добавить в скором времени. Плюс все запросы работали только через jsonp потому что policy не позволяла делать кроссайт запросы. Хотя в phonegap нашли решение этой проблемы.
    • +1
      Есть еще www.tidesdk.org/ — бесплатный. С его помощью заворачивал одну «софтину» на extjs
  • –8
    Как? Тут до сих пор нет картинки про буханку хлеба и троллейбус?
    • 0
      Да ладно, оригинальная же идея — засунуть сервер и клиент в одно и то же приложение.

      Сперва выглядит дико, я допускаю это; но затем ответ на вопрос «но зачем?» становится очевиден: затем, чтобы не переписывать сервер с нуля в форме так называемого «одностраничного» веб-приложения, а пользоваться этим сервером в готовом виде. (Ну если сервер готов уж совершенно — так что целая куча совершённого ранее труда не должна просто так уйти, как говорится, коту под хвост.)

      Вот для разработки GUI-приложений «с нуля» я такой подход не рекомендовал бы.
      • –4
        Митгол.
    • –1
      И что вас смущает? Поделитесь своими проблемами с авторами www.mapbox.com/tilemill/ или www.greenheartgames.com/app/game-dev-tycoon/
  • +1
    Вызывает вопрос поддержка технологий вебкитом, встроенным в node-webkit.js. Судя по всему, node-webkit использует какой-то свой форк вебкита, в связи с чем какие-то новшества могут отсутствовать. К примеру, сделать 3D игрушку на WebGL и затем распространять просто так законно не получится.
    • +2
      Каждый раз поднимается этот вопрос, но ведь уже давно понятно, что подобные хаки что с node-webkit, что с phonegap / appcelerator, sencha desktop, qtwebkit не подходят для тех вещей, где нужна производительность. Написать игрушку на webgl — круто, да, но только для себя самого. Такие «обёртки» подходят для «формочных офисных приложений». Когда нужно быстро, дёшево накидать — и чтоб работало.
      • 0
        appcelerator явно лишний в этом ряду. У него конечно производительность тоже страдает, но он все таки не является оберткой-браузером
      • 0
        Да дело не столько в производительности, её, кстати, достаточно: тот же pixi.js показывает весьма впечатляющий результат. Заманчива именно перспектива писать приложение, которое как в браузере можно запускать, так и на десктопе.
  • 0
    А запустить вторую копию приложения? Или второе приложение, выполненное с использованием этого подхода?
    • 0
      Как вариант:
      Номер порта который прослушивает «серверная» часть необходимо сгенерировать динамически. Функцию startServer выполнить не в виде immediate-function, а обычной функцией с параметром (номер порта) и вызывать её из webkit`а. Если приложение работает в классическом варианте предусмотреть передачу номера порта через параметры командной строки.
      • 0
        Да, с этим можно жить, но вариант не оч крутой. То есть можно забиндиться на порт, который потом захочет занять другое приложение, на чей порт мы случайно попали при генерации.
        • 0
          Возможно, отвечать на эту реплику через год с лишним — достаточно поздно; но я всё же отвечу (в интересах будущих читателей), что свободный порт можно сгенерировать вон тем модулем.
  • 0
    При таком подходе теряется возможность использовать скоуп node-webkit. Получается, что вы просто показываете сайт в милом окошке, все плюшки node-webkit придется забыть.
    • 0
      Согласен, это довольно логичный вывод.
      • 0
        Прошу прощения, написал не подумав: в манифесте node-webkit можно использовать ключ node-remote (более подробно тут), в котором указывается маска адресов / сайтов, которые могут использовать node-webkit скоуп (тема на github по этому поводу).

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.