Краткий ответ.
"Можно ли удалить скрипты перед публикацией пакета?"
npm не включает встроенную функцию удаления скриптов из package.json
.
Длинный ответ с решением.
"Возможно ли это? Или мне следует подумать о другом способе?"
Существует несколько встроенных функций, известных как Пре- и пост-хуки, которые можно использовать для удовлетворения ваших требований, хотя и довольно нестандартным образом. Соответствующие хуки prepublish
и postpublish
описаны в документации следующим образом;
prepublish: Запустить ДО того, как пакет будет упакован и опубликован, а также на локальном npm install
без каких-либо аргументов...
postpublish: запускать ПОСЛЕ публикации пакета.
Синопсис решения:
Используйте prepublish
скрипт в своих проектах package.json
для вызова пользовательского скрипта nodejs. Этот скрипт nodejs выполняет следующие действия:
- Reads the original
package.json
data and caches it.
- Удаляет определенные скрипты/ключи из раздела
scripts
файла package.json
.
- Записывает измененные данные обратно в исходный
package.json
.
Используйте postpublish
скрипт в своих проектах package.json
для вызова другого пользовательского скрипта nodejs. Этот вторичный скрипт nodejs выполняет следующие действия:
- Reverts the content of
package.json
back to it's original state.
Примеры кода/суть.
Следующий скрипт nodejs будет выполнять задачи, упомянутые в первом пункте выше. Назовем его cleanse-pkg.js
.
cleanse-pkg.js
const fs = require('fs');
const path = require('path');
// Define absolute paths for original pkg and temporary pkg.
const ORIG_PKG_PATH = path.resolve(__dirname, '../package.json');
const CACHED_PKG_PATH = path.resolve(__dirname, '../../cached-package.json');
// Obtain original `package.json` contents.
const pkgData = require(ORIG_PKG_PATH);
if (process.argv.length <= 2) {
throw new Error('Missing npm scripts key/name argument(s)');
}
// Get list of arguments passed to script.
const scriptsToRemove = process.argv[2].split(',');
const devDepsToRemove = process.argv[3] ? process.argv[3].split(',') : [];
// Write/cache the original `package.json` data to `cached-package.json` file.
fs.writeFile(CACHED_PKG_PATH, JSON.stringify(pkgData), function (err) {
if (err) throw err;
});
// Remove the specified named scripts from the scripts section.
scriptsToRemove.forEach(function (scriptName) {
delete pkgData.scripts[scriptName];
});
// Remove the specified named pkgs from the devDependencies section.
devDepsToRemove.forEach(function (pkgName) {
delete pkgData.devDependencies[pkgName];
});
// Overwrite original `package.json` with new data (i.e. minus the specific data).
fs.writeFile(ORIG_PKG_PATH, JSON.stringify(pkgData, null, 2), function (err) {
if (err) throw err;
});
Следующий вторичный скрипт nodejs выполнит задачу, упомянутую во втором пункте выше. Назовем его restore-pkg.js
.
restore-pkg.js
const fs = require('fs');
const path = require('path');
// Define absolute paths for original pkg and temporary pkg.
const ORIG_PKG_PATH = path.resolve(__dirname, '../package.json');
const CACHED_PKG_PATH = path.resolve(__dirname, '../../cached-package.json');
// Obtain original/cached contents from `cached-package.json`.
const pkgData = JSON.stringify(require(CACHED_PKG_PATH), null, 2) + '\n';
// Write data from `cached-package.json` back to original `package.json`.
fs.writeFile(ORIG_PKG_PATH, pkgData, function (err) {
if (err) throw err;
});
// Delete the temporary `cached-package.json` file.
fs.unlink(CACHED_PKG_PATH, function (err) {
if (err) throw err;
});
Реализация и использование.
Скрипты prepublish
и postpublish
определены в проектах package.json
следующим образом:
Надуманный оригинальный package.json
{
...
"scripts": {
"keep": ... ,
"a": ... ,
"b": ... ,
"prepublish": "node .scripts/cleanse-pkg \"a,b,prepublish,postpublish\"",
"postpublish": "node .scripts/restore-pkg"
},
...
}
Обратите внимание на часть \"a,b,prepublish,postpublish\"
в сценарии prepublish
. Это определяет аргумент для передачи в cleanse-pkg.js
(т. е. в нем перечислены имена каждого сценария, который необходимо удалить перед публикацией). Каждый именованный скрипт, подлежащий удалению, должен быть; предоставляется как одна строка, разделяется запятыми и не должен содержать пробелов.
И cleanse-pkg.js
, и restore-pkg.js
находятся в скрытой папке с именем .scripts
, которая сама находится на верхнем уровне каталога проектов (то есть на том же уровне, что и проекты package.json
). Оба скрипта nodejs можно перемещать по желанию, а пути к ним при необходимости переопределять в соответствующем npm-script .
Учитывая надуманное package.json
выше, фактическое содержимое package.json
в итоговом опубликованном tar-архиве будет следующим:
Результирующий/опубликованный package.json
{
...
"scripts": {
"keep": ...
},
...
}
Пакеты в разделе devDependencies.
Возможно, в разделе devDependencies
ваших проектов package.json
есть пакеты, которые вы также хотите удалить из опубликованного package.json
.
(Примечание. Все пакеты, перечисленные в разделе devDependencies, не загружаются при хотя пользователь устанавливает через npm-реестр).
Однако, возможно, вы все равно захотите их удалить. Если это требование, то cleanse-pkg.js
также принимает необязательный второй аргумент. Этот аргумент аналогичен первому аргументу, согласно которому каждый именованный пакет, подлежащий удалению из раздела devDependencies
, должен быть; предоставляется как одна строка, разделяется запятыми и не должен содержать пробелов.
Предположим, что исходный package.json
на этот раз выглядит следующим образом:
Надуманный оригинальный package.json
{
...
"scripts": {
"keep": ... ,
"a": ... ,
"b": ... ,
"prepublish": "node .scripts/cleanse-pkg \"a,b,prepublish,postpublish\" \"x,z\"",
"postpublish": "node .scripts/restore-pkg"
},
"devDependencies": {
"x": "^1.0.2",
"y": "^0.8.1",
"z": "^0.8.1"
},
...
}
- Note the additional second
\"x,z\"
argument added to the prepublish
script to specify which packages to omit from the devDependecies
section.
На этот раз, учитывая надуманное package.json
выше, фактическое содержимое package.json
в итоговом опубликованном tar-архиве будет следующим:
Результирующий/опубликованный package.json
{
...
"scripts": {
"keep": ...
},
"devDependencies": {
"y": "^0.8.1"
},
...
}
Бег
В этом решении предполагается, что npm publish будет запущен с использованием одного из следующих методов:
- Из каталога проекта без каких-либо аргументов. Например.
npm publish
.
- Указав путь к своим проектам
package.json
. Например. npm publish path/to/package.json
.
Это не сработает, если указать URL-адрес или путь к сжатому tar-архиву, содержащему одну папку с файлом package.json
внутри.
Дополнительные примечания
Чтобы предотвратить публикацию обоих служебных скриптов nodejs (cleanse-pkg.js
и restore-pkg.js
), их следует добавить в ваши проекты .npmignore. Учитывая расположение обоих этих файлов, описанное выше, вы можете добавить запись .scripts
в .npmignore
.
Оба служебных скрипта nodejs, cleanse-pkg.js
и restore-pkg.js
, определяют:
- An absolute path to the original
package.json
file.
- Абсолютный путь, куда должен быть записан временный файл
cached-package.json
. В настоящее время он сохраняется на один уровень выше/вне каталога проекта, чтобы избежать его публикации).
Если вы решите сохранить cleanse-pkg.js
и restore-pkg.js
в месте, отличном от описанного выше, пути в следующем фрагменте кода необходимо будет переопределить по мере необходимости в обоих файлах.
const ORIG_PKG_PATH = path.resolve(__dirname, '../package.json');
const CACHED_PKG_PATH = path.resolve(__dirname, '../../cached-package.json');
person
RobC
schedule
16.02.2018