SQLite и NW.js — пошаговая инструкция для создания крепкой дружбы

    Привет, Хабр и его обитатели! Захотелось изваять нечто на HTML и JS, чтобы было десктопное и удобное. Что для этого нужно? Правильно. Node.js и NW.js или Electron. Поглядев на слабые попытки холивара NW vs Electron и почитав документацию и того и другого было принято решение для начала пощупать NW.js.

    Но вот ведь засада. Выполнение npm i sqlite3 устанавливает только те библиотеки, которые могут исполняться при непосредственном запуске через node. А если попытаться подключить скрипт в html и запустить этот html в NW.js, то ничего у нас не выйдет. Гугл сотоварищи выдает только один рецепт включения sqlite в проект на nw.js, да и тот приходится вытаскивать из кэша. Да и устарел он уже. Посему было потрачено пару дней на изучение проблематики и поиск рабочего решения. Прошу под кат.

    Итак. Для начала была собрана машина «из того что было» и установлена Windows 7 x32 с пакетом .NET 4.7.1 (потребуется для Visual C++). Почему 32 бита? Решил начать с малого. Хотя, как оказалось, создание модуля под x64 не требует исполнения на x64 системе.

    Затем был поставлен Node.js версии 10.8.0 Хотя на момент окончания экспериментов уже появилась 10.9.0. Но тут я решил послушать знающих людей:



    Поразмышляв, решил, что делаю все-таки для LTS, хотя не совсем понятно, где у них у всех LTS, а где нет. Предположил, что non-LTS — это беты, альфы и ночные сборки.

    Хотя, как любой недоучка сделал все наполовину и следующую рекомендацию на выполнил:

    Рекомендация из документации для LTS-releases
    On Windows, you need to replace the file
    <npm-path>\node_modules\node-gyp\src\win_delay_load_hook.cc with the one at github.com/nwjs/nw.js/blob/nw18/tools/win_delay_load_hook.cc before installing modules with node-gyp or npm.

    Ну не нашел я этот файл у себя на компе. Наверное, потому что не ставил node-gyp.

    Для ноды ставим (крайне необходимо делать из командной строки с правами администратора)

    npm i -g nw-gyp

    Собственно говоря, замена node-gyp
    nw-gyp is a hack on node-gyp to support NW.js specific headers and libraries.

    Далее — качаем Visual Studio Community Edition (текущая ссылка легко находится в любимом поисковике) — на момент написания статьи текущая версия 2017. Что для нас немаловажно — она содержит в себе Build Tools 2015 — пока нативные модули в ноде собираются только с этой версией и более свежих не поддерживают. Скачиваем инсталлятор, запускаем и ставим одну галочку в закладке «Отдельные компоненты» — Набор инструментов VC++ 2015.3 v14.00 (v140) для ПК



    Добавившийся Windows 8.1 SDK также необходим, поэтому устанавливаем все три пункта. Установка в данном виде приводит к скачке 2,89 гигабайт всякого нужного.

    Едем дальше — качаем змейку. Причем версии 2.7. Устанавливаем, по умолчанию в C:\Python27.
    А теперь — внимание! Засада.

    Инсталлятор по умолчанию считает, что необязательно добавлять в PATH расположение питончика, поэтому устраняем это недоразумение на этапе установки



    Похожая засада преследует многих разработчиков при сборке самых разных модулей для ноды. А все потому, что мелкомягкая корпорация также не считает нужным прописывать пути к своим творениям. Гитхаб просто завален ошибками сборки из-за того, что после установки в PATH не попадают пути к сборочным инструментам. Исправляем и это недоразумение — правим переменную среды, чтобы она позволяла сборке пройти если и не очень гладко, то хотя бы без ошибок. Вот что получилось у меня (разбил на строки для лучшего восприятия)

    >echo %PATH%
    C:\Python27\;
    C:\Python27\Scripts;
    C:\Windows\system32;
    C:\Windows;
    C:\Windows\System32\Wbem;
    C:\Windows\System32\WindowsPowerShell\v1.0\;
    C:\Program Files\nodejs\;
    C:\Users\Den\AppData\Roaming\npm;
    C:\Program Files\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin;
    C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\v140;


    Выделенное жирным шрифтом — то, что необходимо добавить вручную. Естественно, убедившись, что эти пути существуют.

    Обязательный пункт — перезагрузка.

    Ну и теперь собственно сборка. Я пользовался менеджером FAR, но никто не запрещает и олдскульный cmd

    c:\
    md app
    cd \app
    npm init
    npm install sqlite3 --build-from-source --runtime=node-webkit --target_arch=ia32 --target=0.32.1 --msvs_version=2015

    для x64 меняем --target_arch=x64.

    Ну собственно и всё. Если все сделано правильно, то сборка проходит с некоторым количеством сообщений типа

    ..\src\database.cc(672): warning C4996: 'Nan::MakeCallback': объявлен deprecate [C:\app\node_modules\sqlite3\build\node_sqlite3.vcxproj]
    C:\app\node_modules\nan\nan.h(929): note: см. объявление "Nan::MakeCallback"
    c:\app\node_modules\nan\nan_new.h(208): warning C4244: аргумент: преобразование "sqlite3_int64" в "double", возможна потеря данных (компилируется исходный файл ..\src\database.cc) [C:\app\node_modules\sqlite3\build\node_sqlite3.vcxproj]

    но в итоге модуль собирается и располагается в
    C:/app/node_modules/sqlite3/lib/binding/node-webkit-v0.32.1-win32-ia32\node_sqlite3.node

    Нюанс сборки — при каждой сборке папка node_modules/sqlite3/lib удаляется сборщиком. Поэтому, если есть необходимость собрать два модуля (для каждой архитектуры) — сохраняйте промежуточный результат.

    Спасибо за внимание, напоследок результат эксперимента:

    Собранные модули для NW.js 0.32.1 ia32 && x64 на гуглоДиске
    Share post

    Comments 17

      –2
      И что к чему? Просто расписали мануал как это дело поднять. А кейсы с применением? А зачем вообще это надо — не описано от слова совсем. Статья ни о чем и думающий человек сделает то же самое без статьи тупо по докам
        +2
        По докам не получается, вот ведь в чем засада. Прежде чем расписать этот мануал мне пришлось читать доки — раз, плясать на граблях отсутствия путей — два, гуглить похожие проблемы на гитхабе и вникать в суть граблей — три. И потом — не все универсалы-токаря высшего разряда — я, например, так и не осилил С++ и вообще всё это семейство, приходится сидеть с PHP, JS и 1С. Попробуйте собрать этот же модуль по docs.nwjs.io/en/latest/For%20Users/Advanced/Use%20Native%20Node%20Modules — последний зуб отдам, что ничего не выйдет.
        Если по кейсам есть нужда — можно попробовать написать.
          +1
          Кейсы sqlite — это любое десктопное приложение, что тут расписывать? ничего другого пока не придумали
          0
          nw.js поддерживает браузерный websql api (но без ограничений на размер базы).
          Для многих задач его вполне хватает.
            0
            так то да, я в курсе про websql, однако мне нужен был именно sqlite. Ну и опыт тоже не помешал ))
            0
            Некоторое время назад были такие же проблемы, как у вас, но только с установкой пакетов для Electron'а. Необходимый мне NPM пакет я установил и заставил работать достаточно быстро, но так как я не до конца понимал процесс установки подобных пакетов, то решил потратить немного времени на изучение этого вопроса.

            Большинство NPM пакетов, которые написаны на С/С++, поставляются с заранее скомпилированными *.node файлами под разные операционные системы и версии NodeJS. При установке пакетов под операционную систему и версию NodeJS, для которой нет заранее скомпилированных *.node файлов, происходит автоматическая компиляция NPM пакета из исходных файлов с использованием пакета node-gyp или node-pre-gyp. Эти два пакеты, можно так сказать, делают одно и то же — создают *.node файлы из исходников. Так как для Electron'а и NW.js никто, как правило, не компилирует *.node файлы предварительно, то это придеться делать самостоятельно, а если точнее, то компиляция всех необходимых файлов произойдет в автоматическом режиме во время установки пакета, но для ее успешного завершения необходимо выполнить рад условий.

            И так, что же необходимо сделать для корректной установки любых NPM пакетов из исходников:

            1. Установить все зависимости, которые нужны для работы NPM пакета node-gyp.
            Подробное описание процесса установки всех зависимостей можно найти как на NPM странице пакета, так и на GitHub, но, как правило, на GitHub'е находится более актуальная информация, так как данные там обновляются в первую очередь.

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

            Для OS Windows, в большинстве случаев, достаточно ввести следующую команду в консоли с правами администратора:

            npm install --global --production windows-build-tools

            После ввода этой команды произойдет автоматическая установка и настройка всех зависимостей NPM пакета node-gyp.

            Первый этап выполнен. Ничего больше, кроме ввода этой единственной команды, делать не надо.

            После завершения этого этапа вы сможете устанавливать любые NPM пакеты из исходников, но только для текущей используемой версии NodeJS и операционной системы, то есть ни для Electron'a, ни для NW.js вы пока еще не сможете устанавливать пакеты, а если точнее, то установить пакеты вы сможете, но работать они не будут.

            2. Указать переменные окружения NPM, которые использует пакет node-gyp/node-pre-gyp в процессе своей работы.
            Именно значения переменных окружения NPM определяют для какой версии операционной системы и NodeJS необходимо компилировать устанавливаемые пакеты.

            Вариантов установки переменных окружения есть несколько, но здесь я расскажу только об одном варианте, который, как я считаю, лучше всего подходит при установке пакетов и дальнейшего их использования в NW.js и Electron'е.

            Что необходимо сделать:

            1. Создать в директории текущего проекта, где находится файл package.json, файл .npmrc (с точкой в начале).

            2. Добавить в этот файл все необходимые переменные окружения NPM. Пример файла для NW.js v0.32.3 64-bit:

            # комментарии в файле стирать не обязательно

            runtime=node-webkit # node, electron, node-webkit
            target=0.32.3 # используемая версия NW.js
            arch=x64 # архитектура NW.js: ia32, x64


            3. Установить все необходимые пакеты используя команду:

            npm install <package-name>

            Вот и все. Теперь вы можете устанавливать любые пакеты из исходников, которые после установки будут корректно работать в NW.js, а не только NPM пакет sqlite3.

            Несмотря на всю простоту установки новых пакетов из исходников под NW.js с использованием этого метода, хочу заметить, что данный метод имеет один и очень существенный минус — переменные окружения NPM распространяются на все устанавливаемые вами локальные пакеты. Другими словами, если кроме NW.js вы используете еще что-то, скажем Webpack, для которого необходимо установить какой-то пакет из исходников, то этот пакет, который планируется использовать внутри Webpack'а, будет скомпилирован для использования в NW.js, а не для NodeJS. В следствии чего, устанавливаемый из исходников пакет для Webpack'а, в большинстве случаев, будет работать некорректно. На самом же деле, не стоит слишком расстраиваться, если этот метод, как может показаться изначально, вам из-за этого недостатка не походит. На практике, все пакеты для Webpack'а, которые я устанавливал, у меня прекрасно работали, но правда только потому, что ни один из них не устанавливался из исходников.

            Надеюсь, что эта информация поможет вам лучше разобраться с тем, как происходит установка пакетов из исходников.
              0
              Согласен. Но до электрона я еще не добрался, хотя почитал доку и меня напрягло разделение на два процесса.
              По поводу установки — простейший путь — установить ноду и поставить нужный пакет — проходит без проблем и без каких-либо подготовок, даже без windows-build-tools. Однако сборка под node-webkit у меня не получалась довольно долго (занимался этим вяло и в промежутках), посему и был пройден описанный мной путь.
              Но за подсказки спасибо — возможно, это будет более простой способ на будущее.
              0
              Топикстартеру. Крайне рекомендую создать свой «пускач», где выставляются все ваши переменные. MS не зря в каждый свой продукт вставляет msvcvar.cmd
              Видимые плюсы этого подхода, очистка системных путей и поиск по явно заданному пути.
              В этом отношении можно кинуть булыжник в сторону Android and Java, файлики adb.exe и java.exe на любой машине можно найти в 10 -20 экземплярах.

                0
                Я с NW.js использовал IndexDB. Хорошая NoSQL БД.
                  0

                  Я пока решил протестировать sqlite, предполагаются достаточно большие объемы с несложными запросами. Когда проект будет в той стадии готовности, на которой можно будет анализировать производительность, начну испытывать другие БД.

                  0
                  Захотелось изваять нечто на HTML и JS, чтобы было десктопное и удобное
                  Чем всё закончилось? Получилось что-нибудь изваять? Или только выкачали с Сети несколько гигабайт дерьма, загадили реестр и память, и всё?
                    0

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

                      0
                      ОК, ждём продолжения.
                        0

                        Думаете, кому-то будет интересен очередной sql-explorer, написанный на js с применением vue.js для фронта, express для бэка и все это в одном флаконе под nw.js? Если да, то буду готовить и для публикации тоже))

                          0
                          Конкретный результат (в частности, очередной sql-explorer) не очень интересен, но интересен опыт решения задачи. Для понимания, во что в итоге выливается применение технологии. Пока что с учётом установки гигабайтов (и особенно устаревшей версии Питона) и танцев с бубном смотрится не очень, но нужно, конечно, смотреть на результат.
                            0
                            Чем дальше в лес — тем толще партизаны. Вот и все применение технологии. Все не так страшно, если результат удовлетворит. А так — можно ведь и не использовать sqlite в частности, есть альтернативы, не требующие таких жертв. Была у меня возможность — я это испробовал. Дальше буду смотреть — был ли смысл.
                      0

                      Щас бы в 2018 смеяться над десктопными приложениями на js. Atom, VS Code…

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