Если вы не новичок в nodejs, вы скорее всего знаете, что одним из достоинств nodejs является возможность написания нативных модулей. Обычно их используют когда необходим некоторый низкоуровневый доступ к системе. Перед разработчиком нативных модулей встаёт ряд проблем связанных с портированием, тестированием, а также распространением кода. Именно на последней я бы хотел заострить внимание.
Кажется, всё просто: написал модуль, сделал js обёртку, тесты и публикуй. Как бы не так. В отличие от стандартных js модулей, для установки нативных требуется среда сборки — gcc / visual studio / etc. И если в linux дистрибутивах с этим всё просто, в windows системах не каждый скриптописатель имеет у себя установленный c++ компилятор. При этом каждый модуль, у которого ваш будет в зависимостях, также будет требовать для установки среду сборки. Так как же быть?
Думаю, уже почти все используют travis / appveyor для тестирования своего кода. Только нативные модули перед тестированием проходят цикл сборки. Было бы не плохо при публикации пакета забирать из CI все собранные бинарники. К счастью, другие разработчики подумали точно также и создали такую систему. Она состоит из трёх модулей: prebuild помогает компилировать модули, prebuild-ci забирает из CI готовые собранные модули, если в последнем коммите было изменение версии пакета, prebuild-install помогает в установке таких собранных модулей.
Настроить всю эту систему очень просто. Для начала, необходимо настроить сборку. За это отвечает prebuild
, он скачивает правильную версию исходников nodejs и компилирует модуль в папке ./prebuild
. Тут важен один момент.Для того, чтоб при установке зависимостей у вас не началась компиляция с использованием node-gyp
, нужно отключить скрипты инициализации.
yarn install --ignore-scripts
# или
npm i --ignore-scripts
После этого пишете команду сборки prebuild --strip
и всё! Я добавляю ключ --strip
, чтоб наверняка удалить всю ненужную информацию из бинарника. Далее запускается сборка тестов и тут нам поможет prebuild-ci
. Включите его в ваш pipeline тестирования и от сам поймёт, когда нужно забирать и заливать модули:
ava test/*.js && prebuild-ci
Для корректной работы prebuild-ci
, в CI нужно задать env переменную PREBUILD_TOKEN с вашим github токеном. Это нужно для возможности создания github release, а также загрузки собранных бинарников в этот релиз. Токены задаются на странице https://github.com/settings/tokens. Нажимаете на Generate new token
, задаёте имя и нажимаете на Generate token
. Я рекомендую задать права на repo
, хоть авторы и пишут, что дефолтных должно хватить. Подробнее о токенах в оригинальном readme.
После этого в следующий раз, когда вы сделаете релиз, все собранные в CI модули попадут в github releases. Настоятельно рекомендую дождаться завершения всех тестов и сборки всех модулей перед публикацией пакета в npm. Кстати, если вы используйте np
для публикации пакетов, там есть соответствующее issue.
В конце нужно указать менеджеру пакетов как устанавливать модули. Для этого существуют npm scripts и стадия install
. Она срабатывает после установки модуля. Менеджер пакетов запустит prebuild-install
, а он в свою очередь сходит за готовыми бинарниками. Тем не менее рекомендуется задать node-gyp rebuild
в конце, чтоб пользователи, для которых готового пакета не нашлось, могли собрать модуль стандартным способом.
"scripts": {
"install": "prebuild-install || node-gyp rebuild"
}
Подключить готовый модуль можно с помощью bindings. Теперь, сделав эти несколько простых шагов, ваши пользователи скажут вам спасибо. Посмотреть как эта система выглядит вся вместе можно в node-process-list или leveldown.
Комментарии (10)
vintage
05.05.2017 08:06Самое печальное, что node-gyp потребует установленного (внезапно!) питона, причём, емнип, второй версии.
zorro1211
09.05.2017 05:33Есть печенье для утоления печали https://github.com/felixrieseberg/windows-build-tools :)
vintage
09.05.2017 10:12Печаль-то не из-за того, что вручную питон ставить, а из-за того, что его вообще нужно ставить. Неужели нельзя было на самой ноде запилить необходимые для сборки скрипты?
MikailBag
09.05.2017 20:32Можно вклеить питон в ноду.
Node-gyp это обертка над питоновской системой сборки gyp.
Поэтому надо либо локально ставить питон при установке ноды, либо уходить на другую систему сборки.
jehy
Несколько надуманная проблема со сборкой нативных модулей на windows, имхо. К моему большому удивлению, нода очень неплохо работает под windows, за исключением возни с симлинками… Но зачем? На линуксе поднять гораздо проще. И если так сложилось, что у вас windows сервера, то есть же виртуализация, есть вагрант и докер…
Ну а если у вас правда есть необходимость работать именно в windows среде, то для сборки нативных модулей хватает visual studio express. Или даже какого-то её куска — помню дебаты по этому поводу, не знаю, чем закончились.
К тому же, вряд ли у вас нативные бинарники сферические в вакууме — они наверняка потребуют неких динамических зависимостей. И если в момент компиляции можно чётко увидеть, чего не хватает, то при запуске это может быть не столь очевидно.
ReklatsMasters
Не у каждого разработчика есть studio с компиляторами. И если у вы автор нативного модуля, тогда да, у вас полностью настроенное окружение. Однако, если я, например, делаю сайтики на реакте, мне совершенно незачем держать студию у себя. К тому же вы не знаете, на какой системе ваш модуль будет использоваться.
Считаю, что нужно создавать меньше проблем другим разрабам.
jehy
Если вы делаете сайтики на реакте, то вам нафиг не сдались нативные модули :)
Например, использовать для получения списка процессов и их данных нативные модули вместо банального child_process exec это просто странное и стрёмное извращение.
А если у вас хайлоад, сложные вычисления, алгоритмы, нейросети и криптография, то проблем один раз поставить ради этого бесплатную студию никаких нет…
KhodeN
есть node_sass, который нативный и часто нужен даже простому фронтэду
jehy
И обязательно нужен именно под windows?