Использование npm для глобальной установки приложений, наделённых GUI и основанных на nw.js
Команда «npm install» в менеджере пакетов npm чаще всего употребляется для локальной установки зависимостей некоторого модуля, совершаемой в его подкаталоге »/node_modules».Однако возможен и запуск этой команды с ключом »-g» (от слóва «global»). Он обеспечивает установку указанного ей пакета в некоторое глобальное (то есть общее для всей системы) место. Кроме того, в PATH (для последующего запуска из любого желаемого каталога) оказывается прописанною та команда, которая была указана в свойстве «bin» в файле package.json у установленного пакета.
Таким общим местом, согласно документации, под Windows служит подкаталог »/node_modules» в каталоге установки Node. В остальных же системах таким общим местом чаще всего оказывается каталог »/usr/local/lib/node_modules» (тогда как Node там устанавливается в каталог »/usr/local/bin»).
Обыкновенно этот подход употребляется для глобальной установки различных утилит, предназначенных для употребления из командной строки. Вот некоторые примеры:
Команда «npm install jshint -g» обеспечивает появление в PATH команды «jshint», служащей для запуска JSHint. Команда «npm install browserify -g» обеспечивает появление в PATH команды «browserify», служащей для запуска Browserify. Команда «npm install less -g» обеспечивает появление в PATH команды «lessc», служащей для запуска Less.js. Однако на CLI (на командной строке) свет клином не сошёлся — и читателям Хабрахабра должно уж вполне быть известно, что приложение на языке JavaScript, употребляющее API Node.js, можно снабдить и GUI (графическим интерфейсом пользователя), сочинённым на языках HTML и CSS. Для этого придётся и запускать такое приложение вместо Node на том движке, который до прошлого года назывался node-webkit, а в нынешнем (2015) году оказался 14 января переименованным в nw.js.Ваши GUI-приложения также могут глобально быть установлены в системе из npm-пакета при помощи npm. Давайте поговорим об этом.
Первый шаг ваш понятен: непременно понадобится засунуть в npm-пакет исходный код самогó вашего GUI-приложения, и засунете.
Однако для запуска этого кода потребуется также движок nw.js, а вот его-то помещать в тот же пакет не слишком разумно. Во-первых, объём движка (под Windows составляющий более 80 мегабайтов, например) создаёт угрозу чрезмерной нагрузки на репозиторий npm-пакетов, если засовывать движок в каждый такой пакет. Во-вторых, в зависимости от системы (Windows, Linux, Mac OS X) или от её разрядности (32-разрядная или 64-разрядная) движок должен быть другим — если же засовывать в npm-пакет все шесть возможных версий движка, то тогда не только репозиторий, но и конечный пользователь вздрогнет от суммарного объёма, достигающего без мáлого половины гигабайта.
Для преодоления этой проблемы был создан npm-пакет nw, который GUI-приложение может указать в числе своих зависимостей (в разделе «dependencies» в файле package.json) — и когда этот пакет будет установлен, то запустится определённый в его собственном файле package.json скрипт postinstall, который автоматически скачает из Интернета именно ту версию nw.js, которая сгодится для конкретной конечной операционной системы.
Следует заметить ещё, что пакет nw определяет (в свойстве «bin» в файле package.json) ещё и команду «nw»; следовательно, GUI-приложение может указать эту команду в качестве собственного скрипта «start», после чего запустить GUI-приложение можно будет, подав команду «npm start» в его каталоге.
Но сразу видно, что это не самый удобный способ запуска GUI-приложения. Куда удобнее было бы обеспечить возможность его запуска командою, состоящею из одного слóва (названия приложения) вместо двух, и притом из любого каталога. Выше ужé было сказано, что этой цели приложение может достигнуть, если в его файле package.json значением поля «bin» будет некоторый скрипт — тогда npm во время глобальной установки автоматически поместит этот скрипт в PATH и придаст ему желаемое название. Ну, а пакет nw экспортирует метод ».findpath ()», которым скрипт может воспользоваться, выясняя конкретное местонахождение скачанного движка nw.js (для последующего запуска движка).
Для примера укажу, что в моём браузере гипертекстового векторного Фидонета открытый исходный код такого скрипта выглядит вот как:
#!/usr/bin/env node
require ('child_process').spawn ( require ('nw').findpath (), ['.'].concat (process.argv.slice (2)), { cwd: __dirname, detached: true, stdio: 'ignore' } ).unref (); Нетрудно видеть, что в нём нет ровным счётом ничего специфически фидонетовского. Следовательно, этот же пример все вы можете без малейших изменений использовать в собственных GUI-приложениях, если предполагаете глобальную установку их из npm-пакета.Непременно обратите внимание на следующие фрагменты этого примера:
«detached: true» и ».unref ()»: движок nw.js запускается в качестве отдельного процесса, а стартовая команда завершает свою работу тотчас же (не ждёт его); «cwd: __dirname»: движок nw.js начинает работу в том каталоге, куда npm глобально установил стартовую команду (исходя из предположения о том, что и всё GUI-приложение лежит там же;, но если этот код вы положили не рядом с файлом package.json, как сделал я, а в некотором подкаталоге, то добавьте в этой строке выход из подкаталога в родительский каталог); »['.'].concat ( process.argv.slice (2) )»: движку nw.js в командной строке сперва передаётся точка (указание взять запускаемое приложение из текущего каталога), а затем — все параметры командной строки стартовой команды; »#!/usr/bin/env node»: под Windows эта строка может показаться не нужною, однако это впечатление иллюзорно (на самом деле npm полагается на наличие этой строки). Рассмотренный выше подход может также быть применён и к установке приложений, вместо nw.js использующих более ранний движок node-webkit. Для этой цели вместо npm-пакета nw следует использовать более ранний (и притом неофициальный) npm-пакет — nodewebkit.