Одно из ограничений нативных аддонов в том, что их нужно компилировать под каждую целевую платформу и архитектуру. Без готовых бинарников каждый пользователь, устанавливающий ваш пакет, должен иметь рабочий C/C++-тулчейн на своей машине.
node-pre-gyp решает это, позволяя вам собирать бинарники заранее, загружать их в удалённое место и давать пользователям скачивать нужный бинарник во время установки — откатываясь к компиляции из исходников только если подходящего бинарника нет.
Обратите внимание, что поддержка Node-API была добавлена в node-pre-gyp в версии 0.8.0.
Эта страница описывает изменения, необходимые Node-API-аддону для поддержки node-pre-gyp.
По умолчанию node-pre-gyp загружает бинарники в Amazon S3.
Модуль node-pre-gyp-github добавляет поддержку публикации в GitHub Releases вместо этого.
Перед загрузкой вам нужны:
- Аккаунт Amazon Web Services.
- IAM-пользователь или роль с правом загрузки в S3.
- S3-бакет для хостинга бинарников.
Никогда не храните учётные данные в своём репозитории. node-pre-gyp поддерживает два распространённых подхода к предоставлению учётных данных во время разработки:
-
Файл
~/.node_pre_gyprc:{ "accessKeyId": "xxx", "secretAccessKey": "xxx" } -
Переменные окружения:
export node_pre_gyp_accessKeyId=xxx export node_pre_gyp_secretAccessKey=xxx
Для CI-окружений предпочитайте IAM-роли или короткоживущие учётные данные, а не долгоживущие ключи доступа. Дополнительные варианты см. в документации node-pre-gyp по учётным данным.
Пакет теперь публикуется в скоупе @mapbox. Используйте @aws-sdk/client-s3 как dev-зависимость для шага загрузки.
"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.0"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.0.0"
}Скрипт install должен вызывать node-pre-gyp с --fallback-to-build, чтобы пользователи, у которых нет доступного готового бинарника, всё же могли скомпилировать локально:
"scripts": {
"install": "node-pre-gyp install --fallback-to-build"
}Свойство binary говорит node-pre-gyp, какие версии Node-API поддерживает ваш аддон и где искать/загружать бинарники:
"binary": {
"module_name": "your_module",
"module_path": "./lib/binding/napi-v{napi_build_version}",
"remote_path": "./{module_name}/v{version}/{configuration}/",
"package_name": "{platform}-{arch}-napi-v{napi_build_version}.tar.gz",
"host": "https://your_bucket.s3.us-west-1.amazonaws.com",
"napi_versions": [3]
}Установите module_name в валидный идентификатор C. Массив napi_versions перечисляет, под какие версии Node-API собирать; 3 — разумный минимум для большинства аддонов.
Полный справочник, включая соображения по Node-API, см. в документации node-pre-gyp.
Добавьте post-build target, чтобы скопировать скомпилированный бинарник по пути, указанному в module_path:
{
"target_name": "action_after_build",
"type": "none",
"dependencies": ["<(module_name)"],
"copies": [
{
"files": ["<(PRODUCT_DIR)/<(module_name).node"],
"destination": "<(module_path)"
}
]
}Включите версию Node-API в defines первого target'а, чтобы заголовочные файлы правильно себя сконфигурировали:
"defines": [
"NAPI_VERSION=<(napi_build_version)"
]JavaScript-код, загружающий нативный бинарник, должен динамически разрешать путь к правильному файлу .node:
const binary = require('@mapbox/node-pre-gyp');
const path = require('path');
const bindingPath = binary.find(
path.resolve(path.join(__dirname, './package.json'))
);
const binding = require(bindingPath);Как только всё на месте, соберите из исходников:
npm install --build-from-source./node_modules/.bin/node-pre-gyp package
./node_modules/.bin/node-pre-gyp publishИспользуйте GitHub Actions, чтобы собирать, тестировать и публиковать бинарники для нескольких платформ и архитектур. Типичная матрица workflow покрывает ubuntu-latest, macos-latest и windows-latest, плюс любые нужные вам варианты архитектуры (например, x64, arm64). Примеры конфигураций workflow см. в репозитории node-pre-gyp.