Лучшая практика для обновления npm `prepublish` script для npm @>= 4
Я запускаю npm install
из корневую папку моего образца проекта для ее создания с использованием сценариев в package.json
.
В сборке требуется несколько шагов транспиляции в настоящее время в prepublish
script, но версия npm версии 4 отображает предупреждение о том, что происходит изменение прерывания, что заставило меня поверить в новый prepare
событие сборки script - более надежное будущее.
C:\code\antlr4ts-json>npm install
npm WARN prepublish-on-install As of [email protected], `prepublish` scripts will run only for `npm publish`.
npm WARN prepublish-on-install (In [email protected] and previous versions, it also runs for `npm install`.)
npm WARN prepublish-on-install See the deprecation note in `npm help scripts` for more information.
...
К сожалению, просто перемещение script от prepublish
до prepare
прерывает обратную совместимость: если кто-то запускает npm install
с помощью [email protected]
, шаги сборки в prepare
молча игнорируются.
Что лучше всего подходит для обновления моего времени сборки script? В идеале я хотел бы обновить свой package.json
, чтобы npm install
работал для любого npm @ >= 3, но в качестве альтернативы генерирует ясное сообщение об ошибке, указывающее, что npm @ >= 4 требуется при запуске npm install
с использованием npm @3.
Bakground: Я пытался включить
"engines": { "npm": ">=4.0.0" },
Благодаря @toomuchdesign (и другим), я понимаю, почему это не делает то, что я хочу; engines
проверяет только, когда мой пакет установлен как зависимость, а не кто-то создает его из источников. Это имеет смысл.
Я отслеживал предысторию этого запланированного изменения до npm issue # 10074, что объясняет, почему необходимо изменить разрыв. Однако я все еще не понимаю, как лучше справляться с переходом.
Ответы
Ответ 1
Я нашел лучшее решение, используя check-node-version
; этот пакет имеет интерфейс командной строки, что упрощает его использование для этой цели. Вот шаги, которые я бы предложил в качестве наилучшей практики:
- Добавьте зависимость развития с помощью
npm install -D [email protected]
,
- Переименуйте существующий
prepublish
script в prepare
,
- Добавьте замену
prepublish
script для обратной совместимости и предложите обновить npm (см. ниже).
Мой package.json теперь выглядит примерно так:
"scripts": {
"prepare": "npm run antlr4 && tsc",
"prepublish": "check-node-version --npm \">=4\" || npm run prepare",
"antlr4": "rimraf gen && antlr4ts Json.g4 -o gen -visitor",
...
},
"devDependencies": {
"check-node-version": "^1.1.2",
...
При таком подходе:
-
npm install
всегда запускается prepare
script, даже с установленным [email protected]
. Это должно работать правильно, если [email protected]
установлен (непроверен.)
-
В [email protected]
есть даже полезное сообщение об обновлении npm, но поскольку script использует || npm run prepare
для имитации поведения более поздних версий, script продолжается после ошибки.
-
Если позже мне понадобится жесткая зависимость от [email protected]
, удаление части || npm run prepare
приведет к остановке script, если она запущена на [email protected]
.
Вот что выглядит построение с помощью [email protected]
:
C:\code\antlr4ts-json>npm i
> [email protected] prepublish C:\code\antlr4ts-json
> check-node-version --npm ">=4" || npm run prepare
node: v6.9.1
npm: v3.10.10
Error: Wanted npm version ">=4" (>=4.0.0)
To install npm, run `npm install -g [email protected]>=4`
> [email protected] prepare C:\code\antlr4ts-json
> npm run antlr4 && tsc
Ответ 2
NPM docs утверждают, что поле engines
выдает ошибку только тогда, когда ваш пакет установлен как зависимость:
Если пользователь не установил флаг конфигурации engine-strict
, поле [двигатели] является рекомендательным, будет выдавать предупреждения, когда ваш пакет установлен как зависимость.
Как разработчик /mantainer проекта, вы не должны видеть никаких предупреждений из вашего поля engines
.
Поскольку вам нужно скомпилировать ваши файлы при запуске только npm install
, вы можете просто использовать postinstall
hook.
Также обратите внимание, что prepublish
останется, он просто изменит свое поведение на [email protected]
, выстрелив только до publish
hook.