Npm postinstall только на разработке
У меня есть модуль npm со следующим package.json
{
"name": "my-app",
"version": "0.0.0",
"scripts": {
"prepublish": "bower install",
"build": "gulp"
},
"dependencies": {
"express": "~4.0.0",
"body-parser": "~1.0.1"
},
"devDependencies": {
"gulp": "~3.6.0",
"bower": "~1.3.2"
}
}
Когда я развертываю свое приложение в рабочей среде, я не хочу устанавливать devDependecies, поэтому я запускаю npm install --production
, Но в этом случае prepublish
Скрипты называются, но это не нужно, потому что я использую CDN ссылки в производстве.
Как вызвать скрипт postinstall только после npm install
но не после npm install --production
?
8 ответов
Более новые версии npm (& Yarn) включают поддержку prepare
скрипт, который запускается после каждого install
запустить, но только в режиме разработки. Так же prepublish
устарела. Этого должно быть достаточно:
{
scripts: {
"prepare": "bower install"
}
}
Документы: https://docs.npmjs.com/misc/scripts
Я думаю, что вы не можете выбрать, какие сценарии запускаются на основе --production
аргумент. Однако вы можете предоставить скрипт, который проверяет NODE_ENV
переменная и работает только bower install
если это не "производство".
Если вы всегда находитесь в среде unix-y, вы можете сделать это следующим образом:
{
scripts: {
"prepublish": "[ \"$NODE_ENV\" != production ] && bower install"
}
}
Это работает, только если вы работаете в среде, подобной Unix:
NPM задает для переменной среды значение "true", когда установка запускается с параметром --production. Чтобы запустить скрипт postinstall, только если установка npm не была запущена с --production, используйте следующий код.
"postinstall": "if [ -z \"$npm_config_production\" ]; then node_modules/gulp/bin/gulp.js first-run; fi",
Решение, которое в меньшей степени зависит от природы Unix вашей оболочки:
"scripts": {
"postinstall": "node -e \"process.env.NODE_ENV != 'production' && process.exit(1)\" || echo do dev stuff"
},
Я работаю с Windows, OSX и Linux, поэтому я использую решение, не зависящее от среды, чтобы решить эту проблему:
В обработчике postinstall я выполняю js-скрипт, который проверяет переменную process.env.NODE_ENV и выполняет всю работу.
в моем конкретном случае я должен выполнить gulp задачу только в среде разработки:
часть package.json
"scripts": {
"postinstall": "node postinstall"
}
все скрипт postinstall.js
if (process.env.NODE_ENV === 'development') {
const gulp = require('./gulpfile');
gulp.start('taskname');
}
последний ряд gulpfile.js
module.exports = gulp;
важно экспортировать gulp из gulpfile.js, потому что все задачи находятся в этом конкретном экземпляре gulp.
У меня есть более общая проблема - где я хочу пропустить запуск postinstall
скрипт при локальной (прямой) установке - например, когда я разрабатываю пакет и запускаю yarn add --dev my-new-dependency
,
Это то, что я придумал. Работает как с нпм, так и с пряжей.
postinstall.js:
const env = process.env;
if (
// if INIT_CWD (yarn/npm install invocation path) and PWD
// are the same, then local (dev) install/add is taking place
env.INIT_CWD === env.PWD ||
// local (dev) yarn install may have been run
// from a project subfolder
env.INIT_CWD.indexOf(env.PWD) === 0
) {
console.info('Skipping `postinstall` script on local installs');
}
else {
// do post-installation things
// ...
}
package.json:
"script": {
"postinstall": "node postinstall.js",
...
Приземлился здесь, потому что у меня была такая же проблема. Закончилось решением, которое проверяет наличие пакета в node_modules, который, как я знаю, должен быть доступен только в разработке.
{
"scripts": {
"postinstall": "bash -c '[ -d ./node_modules/@types ] && lerna run prepare || echo No postinstall without type info'"
}
}
Концептуально это прекрасно работает для меня, поскольку скрипты подготовки, называемые lerna, в основном предназначены для компиляций ts-to-js.
Я использую модуль if-env. Это менее многословно.
PS: я еще не тестировал на Windows.
Установить с помощью:
npm i if-env
чем в package.json
скрипты:
"postinstall-production": "echo \"production, skipping...\"",
"postinstall-dev": "echo \"doing dev exclusive stuff\"",
"postinstall": "if-env NODE_ENV=production && npm run postinstall-production || npm run postinstall-dev"