Готовые нативные модули для node.js

в 13:00, , рубрики: appveyor, bindings, c++, ci, gcc, github, github releases, github token, JS, leveldown, node-gyp, node-process-list, node.js, nodejs, nodejs addon, np, prebuild, prebuild-ci, prebuild-install, token, travis-ci, Visual Studio

Если вы не новичок в 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.

Автор: Дмитрий Ц

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js