Десктопные приложения на html, css и js для windows, mac os, linux. Подробный обзор nw.js (бывший node-webkit)

Что мы сделали

  1. Установили и настроили редактор кода.
  2. Создали рабочую папку и добавили туда файлы нашего проекта.
  3. Научились редактировать и сохранять файлы с кодом.
  4. Установили расширение, чтобы сразу видеть результат вёрстки.

В следующих частях — о добавлении и проверке кода на JavaScript, и о том, как сделать работу с кодом ещё удобнее. Подпишитесь на нашу рассылку, чтобы не пропустить следующие выпуски.

Не знаете, какой код написать?

Знакомство с HTML и CSS на интерактивных курсах — бесплатно.

Регистрация

Нажатие на кнопку — согласие на обработку персональных данных

Почему браузера может быть мало?

Похожие подходы и их недостатки

На данный момент существует несколько различных технологий для создания десктопных приложений на базе веб-технологий. Вот их неполный список:

  • Adobe flash
  • Tide SDK (ex. Titanium Desktop)
  • App.js
  • Brackets Shell
  • Tint
  • И другие…

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

С nw.js все намного проще. Если вы разрабатываете веб-приложения и имеете немного опыта работы с node.js, то уже через несколько часов вы поймете как писать и собирать десктопные приложения под mac, windows и linux.

От node-webkit к nw.js. Немного истории

В 2011 году разработчик из Китая Roger Wang основал проект node-webkit, основной задумкой которого стало использование веб-технологий для написания полнофункциональных кроссплатформенных десктопных приложений. Как уже понятно из названия, основными составляющими проекта стали Node.js и Webkit (Chromium).

Шли годы и в апреле 2013-го Chromium, а вместе с ним и проект node-webkit переехал на новый движок Blink (форк Webkit-а). В добавок к этому с января 2020 проект начал использовать io.js вместо node.js.

В итоге изначальное название “node-webkit” стало совсем не актуальным и было принято решение переименовать проект в nw.js. Бытует мнение, что теперь в буквах NW заложен новый смысл – “Native Web”.

Основными спонсорами проекта до сих пор являются intel и Gnor Tech.

Основная идея. Зачем “скрещивать” Chromium c node.js?

Когда мы говорим о десктопных приложениях, мы представляем себе некий графический интерфейс, взаимодействуя с которым мы осуществляем изменения на системном уровне операционной системы (например, копируем файлы, запускаем процессы, выполняем системные команды и т.п.)

Для того, чтобы понять всю мощь идеи nw.js, давайте коротко рассмотрим основные составляющие nwjs.

Chromium – браузер с открытым исходным кодом, который разрабатывается силами Google, Opera Software, Яндекс, NVIDIA и других компаний. В качестве движка для отображения веб-страниц в Chromium используется Blink (форк Webkit). В качестве движка для обработки JavaScript используется v8.

node.js(io.js) – это JavaScript runtime на основе движка v8, изначально используемого в Chromium. Он написан на С++ и работает на уровне протоколов прикладного уровня, где ему доступны множество различных API операционных систем, таких как файловая система и сетевые взаимодействия. В силу этого, node чаще всего используется для построения системных приложений и серверов.

Основной идеей nw.js является объединение Chromium и node.js в единый контекст, используя один и тот же v8. Если сказать точнее, node.js использует v8 Chromium-a. Т.е. при помощи Chromium мы можем создать графический интерфейс на основе html, css, js, как и в любом веб-браузере. Но, в отличие от обычного браузера, nw.js позволяет из этого же контекста вызывать функции node.js для работы с системными API операционной системы.

Давайте разберем простейший пример. При помощи модуля fs для io.js мы будем следить за изменениями какого-нибудь файла в системе. В случае, если файл изменился, отобразим его содержимое в div-e c id=”log”.

js

var fs = require(‘fs’); var path = ‘/usr/local/var/log/nginx/error.log’; fs.watchFile(path, function(a){ document.getElementById(‘log’).innerHTML = fs.readFileSync(path, {encoding:’utf8′}); });
Как мы видим, здесь нет сервера и клиента, нет ajax, нет сокетов, нет http, нет обмена данными по сети. Как мы говорили, вся прелесть nwjs заключается в возможности работы с node.js из контекста Chromium.

Как они это сделали

Разработчики nw.js приложили немало усилий для обеспечения единого event loop и построения “моста” между контекстами node.js и chromium. Здесь можно почитать подробнее о технических деталях и проблемах, возникших при реализации этой задумки.

Элементы интерфейса операционной системы.

Nw.js позволяет создавать и управлять элементами интерфейса операционной системы, характерными для десктопных приложений (меню окна, трей, контекстные меню). Также Вы можете получить доступ к буферу обмена, сочетаниям системных клавиш и т.п.

Для этого потребуется всего лишь подключить модуль nw.gui, который уже есть в стандартной поставке. Он дает возможность абстрагироваться от реализации элементов интерфейса в конкретной операционной системе, предоставляя общий API.

var gui = require(‘nw.gui’); gui.Window.get(); //окно gui.Shell(); //оболочка gui.Tray // трей gui.Menu // менюшки gui.Clipboard // буффер обмена gui.Shortcut // сочетания клавиш // …и другие элементы

А теперь давайте посмотрим подробнее на некоторые из вышеописанных возможностей.

Создание системных контекстных меню

js

// Создать пустое меню var menu = new gui.Menu(); // Добавить в него пункты или разделители menu.append(new gui.MenuItem({ label: ‘Ничего не делать’ })); menu.append(new gui.MenuItem({ type: ‘separator’ })); // .. и повесить на них обработчики menu.append(new gui.MenuItem({ label: ‘Сказать «Привет!»‘, click: function() { alert(‘Привет!’) } })); // Показывать в виде контекстного меню document.body.addEventListener(‘contextmenu’, function(e) { e.preventDefault(); // В том месте, где мы кликнули menu.popup(e.x, e.y); return false; }, false);
Вот что мы получим в итоге при клике правой клавишей на окне:

Создание меню окна

js

// Создать верхнее меню var menubar = new gui.Menu({ type: ‘menubar’, title: ‘Menu Title’ }); // В качестве вложенных меню используем такой же код, как в примере c контекстным меню. menubar.append(new gui.MenuItem({ label: ‘Главное’, submenu: menu})); menubar.append(new gui.MenuItem({ label: ‘О нас’, submenu: menu})); //Получить текущее окно и подключить к нему верхнее меню gui.Window.get().menu = menubar;
Результат:

Создание иконок и меню в трее (менюбаре)

js

// Создаем иконку в трее (менюбаре) var tray = new gui.Tray({ title: ‘ololo’, icon: ‘icon.png’, alticon: ‘icon.png’ }); // Добавляем меню при клике на иконке в трее var traymenu = new gui.Menu(); traymenu.append(new gui.MenuItem({label: ‘Тот’, type: ‘checkbox’})); traymenu.append(new gui.MenuItem({label: ‘Этот’, type: ‘checkbox’ })); traymenu.append(new gui.MenuItem({label: ‘Другой’, type: ‘checkbox’})); traymenu.append(new gui.MenuItem({type: ‘separator’ })); // В качестве вложенных меню используем такой-же код как в примере c контекстным меню. traymenu.append(new gui.MenuItem({label: ‘или …’, submenu: menu})); tray.menu = traymenu;
Результат:

Обработка сочетаний клавиш

js

var shortcut = new gui.Shortcut({ key : «Ctrl+Shift+L», active : function() { console.log(‘Нажато сочетание клавиш’, this.key) }, failed : function(msg) { // невозможно зарегистрировать такое сочетание клавиш // возможно, оно уже занято console.log(msg); } }); // регистрируем сочетание клавиш в системе gui.App.registerGlobalHotKey(shortcut); // отписываемся от сочетания клавиш в системе gui.App.unregisterGlobalHotKey(shortcut);

Работа с буфером обмена

js

var clipboard = gui.Clipboard.get(); // получить значение var text = clipboard.get(‘text’); // установить значение clipboard.set(‘Привет’, ‘text’); // очистить буфер clipboard.clear();

Начинаем погружение

Для начала скачайте и установите последнюю версию nw.js для Вашей платформы. Далее следуйте указаниям документации для настройки командной строки и алиасов для Вашей операционной системы.

Структура приложения nw.js

Приложение для nw.js состоит из обычных html, css, js файлов, структурированных произвольно. Нет никаких дополнительных правил и условностей по их компоновке.

При запуске nw.js ищет файл манифеста package.json.

Пример package.json

{ «main»: «index.html», «name»: «dummydemo», «description»: «Dummy demo of nnwjs app», «version»: «0.0.1», «keywords»: [ «demo», «nwjs» ], «window»: { «title»: «Dummy demo», «icon»: «icon.png», «toolbar»: false, «frame»: true, «width»: 700, «height»: 400, «position»: «mouse», «min_width»: 400, «min_height»: 200, «max_width»: 800, «max_height»: 600 }, «author»: «nedudi», «license»: «MIT», «dependencies»: { «moment»: «latest», «handlebars»: «^2.0.0» } }
Этот файл ничем не отличается от обычного package.json в node.js, за исключением того, что он содержит дополнительные параметры: window, user-agent, chromium-args, js-flags и другие. Они позволяют nw.js настраивать и контролировать поведение Chromium и его окружения, добавлять флаги при запуске node.js, менять режим отображения, размеры окна, иконки, точку входа в приложение и множество других установок.

Для примера мы создадим файл index.html и добавим немного CSS.

index.html

Привет, NW.JS!
Затем откроем консоль и наберем:

$ nw my/lovely/app

где my/lovely/app – путь к папке с приложением, а nw – правильно настроенный алиас для nw.js

И все! В результате запустится десктопное приложение, которое выглядит примерно так:

Настройка отображения окна

Результат, который мы видим очень похож на обычный браузер с адресной строкой. В принципе, это и есть браузер! Да-да, тот самый Chromium, о котором мы говорили.

Однако, в большинстве случаев хочется, чтобы наше творение не выглядело как браузер, а больше походило на привычное десктопное приложение.

Для этого существует целый ряд настроек, доступных в package.json. Давайте подробнее остановимся на некоторых из них.

Для начала можем убрать тулбар.

package.json

… «window»: { «toolbar»: false } …
При желании можно скрыть фрейм окна.

package.json

… «window»: { «toolbar»: false, «frame»: false } …

Или вообще убрать фон окна, оставив только контент.

package.json

… «window»: { «toolbar»: false, «frame»: false, «transparent»: true } …

Kiosk-mode

Еще одной мощной опцией является возможность запуска приложений в Kiosk-mode. Этот режим часто используется в десктопных играх, а также на экранах в публичных местах (например, для показа рекламы на больших мониторах). Выйти из приложения, запущенного в Кiosk-mode не так просто как из браузерного fullscreen. Это можно сделать только при помощи методов API nw.js, Alt-Tab или Ctrl-Alt-Del(Windows), поэтому, разрабатывая приложения, работающие в этом режиме, Вы сами должны позаботиться о наличии в интерфейсе некоторой кнопки “Выход”, которая поможет пользователю его закрыть.

package.json

… «window»: { «kiosk»: true } …
Ну и, наконец, мы просто можем скрыть окно, оставив приложение в фоновом режиме

«window»: { «show»: false }

Сборка приложений на nw.js

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

В стандартных же случаях лучше использовать готовый плагин node-webkit-builder.

Все что нужно сделать, это установить node-webkit-builder и запустить команду nwbuild с указанием пути к папке приложения.

$ npm i -g node-webkit-builder $ nwbuild ./

Если требуется собрать приложение под конкретные операционные системы, их список можно задать с помощью флага -p

$ nwbuild ./ -p win32,win64,osx32,osx64,linux32,linux64

При этом nwbuild сам скачает последние версии nw.js и сделает сборки для всех указанных платформ (каждую в отдельной папке).

Вот что получилось у меня после открытия собранного тестового приложения в различных ОС:

Mac OS

Windows

Ubuntu

Рейтинг
( 1 оценка, среднее 4 из 5 )
Понравилась статья? Поделиться с друзьями:
Для любых предложений по сайту: [email protected]