Если вы не новичок в 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.
Автор: Дмитрий Ц