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


  1. jehy
    03.05.2017 15:10

    Несколько надуманная проблема со сборкой нативных модулей на windows, имхо. К моему большому удивлению, нода очень неплохо работает под windows, за исключением возни с симлинками… Но зачем? На линуксе поднять гораздо проще. И если так сложилось, что у вас windows сервера, то есть же виртуализация, есть вагрант и докер…

    Ну а если у вас правда есть необходимость работать именно в windows среде, то для сборки нативных модулей хватает visual studio express. Или даже какого-то её куска — помню дебаты по этому поводу, не знаю, чем закончились.

    К тому же, вряд ли у вас нативные бинарники сферические в вакууме — они наверняка потребуют неких динамических зависимостей. И если в момент компиляции можно чётко увидеть, чего не хватает, то при запуске это может быть не столь очевидно.


    1. ReklatsMasters
      03.05.2017 15:56

      Не у каждого разработчика есть studio с компиляторами. И если у вы автор нативного модуля, тогда да, у вас полностью настроенное окружение. Однако, если я, например, делаю сайтики на реакте, мне совершенно незачем держать студию у себя. К тому же вы не знаете, на какой системе ваш модуль будет использоваться.
      Считаю, что нужно создавать меньше проблем другим разрабам.


      1. jehy
        03.05.2017 16:13
        +1

        Если вы делаете сайтики на реакте, то вам нафиг не сдались нативные модули :)
        Например, использовать для получения списка процессов и их данных нативные модули вместо банального child_process exec это просто странное и стрёмное извращение.

        А если у вас хайлоад, сложные вычисления, алгоритмы, нейросети и криптография, то проблем один раз поставить ради этого бесплатную студию никаких нет…


        1. KhodeN
          06.05.2017 00:47

          есть node_sass, который нативный и часто нужен даже простому фронтэду


          1. jehy
            06.05.2017 01:06

            И обязательно нужен именно под windows?


  1. vintage
    05.05.2017 08:06

    Самое печальное, что node-gyp потребует установленного (внезапно!) питона, причём, емнип, второй версии.


  1. zorro1211
    09.05.2017 05:33

    Есть печенье для утоления печали https://github.com/felixrieseberg/windows-build-tools :)


    1. vintage
      09.05.2017 10:12

      Печаль-то не из-за того, что вручную питон ставить, а из-за того, что его вообще нужно ставить. Неужели нельзя было на самой ноде запилить необходимые для сборки скрипты?


      1. MikailBag
        09.05.2017 20:32

        Можно вклеить питон в ноду.
        Node-gyp это обертка над питоновской системой сборки gyp.
        Поэтому надо либо локально ставить питон при установке ноды, либо уходить на другую систему сборки.


      1. ReklatsMasters
        10.05.2017 08:35

        У Fedor Indutny есть порт на js — gyp.js, правда не оконченный