NPM 条件脚本(Windows / Mac)应执行不同的命令)
NPM conditional script (Windows / Mac) shall execute different commands)
用例:
我正在 NPM 中设置一个 prepublishOnly
挂钩,它会删除 "lib" 文件夹,然后将 typescript 源文件转译到一个新的 lib 文件夹中,然后进行 运行 测试.
问题:
两个人应该发布 NPM 包,他们都在不同的 OS (Windows / Mac) 上工作。因此删除文件夹的命令不同
"scripts": {
"build": "tsc",
"clean": "rm -rf lib",
"clean:windows": "if exist lib rmdir /s /q lib",
"lint": "tslint --project tsconfig.json --format stylish src/**/*.ts",
"format": "prettier --write \"**/*.ts\""
},
"husky": {
"hooks": {
"pre-push": "npm run clean:windows && npm run build && npm run test"
}
},
问题:
有没有办法有条件地 运行 NPM 脚本(基于使用的 OS)或者是否有一个删除文件夹命令可以跨这些 OS?
我解决此类问题的方法是使用 gulp
定义一组特定于 os 的任务,因为您在那里编写的代码是 OS-agnostic.
您需要安装 gulp 作为依赖项并在根目录中创建一个 gulpfile.js
。
在其中,定义一个删除文件夹的任务。
var gulp = require('gulp'),
path = require('path'),
fs = require('fs-extra');
const rootFolder = path.join(__dirname);
const libFolder = path.join(rootFolder, 'lib');
gulp.task('clean:lib', function () {
return deleteFolder(libFolder);
});
function deleteFolder(folder) {
return fs.removeSync(folder);
}
gulp.task('deleteLib', ['clean:lib']);
然后,在您的 package.json
脚本中,您可以执行 && gulp deleteLib
。
(确保 gulp 文件中使用的包作为开发依赖项安装在 package.json 中!)
代码未经测试,写在我的脑海中,但这只是给你一个大概的想法。
添加 gulp 到你的工具列表似乎是不必要的,如果你想做的只是通过 npm 脚本在交叉平台方式。对于轻量级解决方案,请考虑以下两种解决方案:
解决方案 1
看看rimraf,它被描述为:
The UNIX command rm -rf
for node.
用法
cd
到您的项目目录和 运行 以下命令:
npm install rimraf --save-dev
将 package.json
中的 clean
脚本更改为以下内容:
"scripts": {
"clean": "rimraf lib",
...
},
从您的 package.json
中删除 clean:windows
脚本,因为它现在是多余的。
注意 我在将它作为本地依赖项安装时并没有取得很大的成功,因此我使用下面的解决方案二。然而,您可能会取得更大的成功 - 所以值得一试。
解决方案 2
以下解决方案使用 shelljs
rm
command which is analogous to the Unix rm -rf
命令,但它用于节点 - 因此它是一个跨平台等效项。
以下步骤显示了如何实现:
cd
到您的项目目录并通过 运行 安装 shelljs 以下命令:
npm install shelljs --save-dev
创建自定义节点脚本如下,我们将文件命名为clean.js
:
const shell = require('shelljs');
process.argv.slice(2).forEach(function(_path) {
shell.rm('-rf', _path);
});
并将其保存到项目根目录中名为 .scripts
的隐藏目录中。例如:
.
├── .scripts
│ └── clean.js
├── lib
│ └── ...
├── node_modules
│ └── ...
├── package.json
├── src
│ └── ...
└── ...
将 package.json
中的 clean
脚本替换为以下内容:
"scripts": {
"clean": "node .scripts/clean lib",
...
},
您也可以将多个路径参数传递给 clean.js
。例如:
"scripts": {
"clean": "node .scripts/clean lib another/folder/path foo/bar",
...
},
文件路径也被处理。例如:
"scripts": {
"clean": "node .scripts/clean path/to/quux.js",
...
},
从您的 package.json
中删除 clean:windows
脚本,因为它现在是多余的。
注释
clean.js
利用节点内置 process.argv
获取调用脚本时传递给 Node 的命令行参数数组。
然后我们 slice() 来自索引 2
的参数数组以确保我们只包含 folder/file 路径参数(例如 lib
) .
最后,我们使用 forEach()
遍历数组中的每个文件夹路径,并在循环的每一轮中调用 shell.rm('-rf', _path);
来删除资产。
编辑/更新:
另一种跨平台解决方案(最初发布此答案时不可用)是利用 shx 包,描述为:
shx
is a wrapper around ShellJS Unix commands, providing an easy solution for simple Unix-like, cross-platform commands in npm package scripts
运行以下命令安装shx
:
npm i -D shx
然后在package.json
中重新定义你的clean
脚本如下:
"scripts": {
"clean": "shx rm -rf lib"
}
用例:
我正在 NPM 中设置一个 prepublishOnly
挂钩,它会删除 "lib" 文件夹,然后将 typescript 源文件转译到一个新的 lib 文件夹中,然后进行 运行 测试.
问题:
两个人应该发布 NPM 包,他们都在不同的 OS (Windows / Mac) 上工作。因此删除文件夹的命令不同
"scripts": {
"build": "tsc",
"clean": "rm -rf lib",
"clean:windows": "if exist lib rmdir /s /q lib",
"lint": "tslint --project tsconfig.json --format stylish src/**/*.ts",
"format": "prettier --write \"**/*.ts\""
},
"husky": {
"hooks": {
"pre-push": "npm run clean:windows && npm run build && npm run test"
}
},
问题:
有没有办法有条件地 运行 NPM 脚本(基于使用的 OS)或者是否有一个删除文件夹命令可以跨这些 OS?
我解决此类问题的方法是使用 gulp
定义一组特定于 os 的任务,因为您在那里编写的代码是 OS-agnostic.
您需要安装 gulp 作为依赖项并在根目录中创建一个 gulpfile.js
。
在其中,定义一个删除文件夹的任务。
var gulp = require('gulp'),
path = require('path'),
fs = require('fs-extra');
const rootFolder = path.join(__dirname);
const libFolder = path.join(rootFolder, 'lib');
gulp.task('clean:lib', function () {
return deleteFolder(libFolder);
});
function deleteFolder(folder) {
return fs.removeSync(folder);
}
gulp.task('deleteLib', ['clean:lib']);
然后,在您的 package.json
脚本中,您可以执行 && gulp deleteLib
。
(确保 gulp 文件中使用的包作为开发依赖项安装在 package.json 中!)
代码未经测试,写在我的脑海中,但这只是给你一个大概的想法。
添加 gulp 到你的工具列表似乎是不必要的,如果你想做的只是通过 npm 脚本在交叉平台方式。对于轻量级解决方案,请考虑以下两种解决方案:
解决方案 1
看看rimraf,它被描述为:
The UNIX command
rm -rf
for node.
用法
cd
到您的项目目录和 运行 以下命令:npm install rimraf --save-dev
将
package.json
中的clean
脚本更改为以下内容:"scripts": { "clean": "rimraf lib", ... },
从您的
package.json
中删除clean:windows
脚本,因为它现在是多余的。
注意 我在将它作为本地依赖项安装时并没有取得很大的成功,因此我使用下面的解决方案二。然而,您可能会取得更大的成功 - 所以值得一试。
解决方案 2
以下解决方案使用 shelljs
rm
command which is analogous to the Unix rm -rf
命令,但它用于节点 - 因此它是一个跨平台等效项。
以下步骤显示了如何实现:
cd
到您的项目目录并通过 运行 安装 shelljs 以下命令:npm install shelljs --save-dev
创建自定义节点脚本如下,我们将文件命名为
clean.js
:const shell = require('shelljs'); process.argv.slice(2).forEach(function(_path) { shell.rm('-rf', _path); });
并将其保存到项目根目录中名为
.scripts
的隐藏目录中。例如:. ├── .scripts │ └── clean.js ├── lib │ └── ... ├── node_modules │ └── ... ├── package.json ├── src │ └── ... └── ...
将
package.json
中的clean
脚本替换为以下内容:"scripts": { "clean": "node .scripts/clean lib", ... },
您也可以将多个路径参数传递给
clean.js
。例如:"scripts": { "clean": "node .scripts/clean lib another/folder/path foo/bar", ... },
文件路径也被处理。例如:
"scripts": { "clean": "node .scripts/clean path/to/quux.js", ... },
从您的
package.json
中删除clean:windows
脚本,因为它现在是多余的。
注释
clean.js
利用节点内置process.argv
获取调用脚本时传递给 Node 的命令行参数数组。然后我们 slice() 来自索引
2
的参数数组以确保我们只包含 folder/file 路径参数(例如lib
) .最后,我们使用
forEach()
遍历数组中的每个文件夹路径,并在循环的每一轮中调用shell.rm('-rf', _path);
来删除资产。
编辑/更新:
另一种跨平台解决方案(最初发布此答案时不可用)是利用 shx 包,描述为:
shx
is a wrapper around ShellJS Unix commands, providing an easy solution for simple Unix-like, cross-platform commands in npm package scripts
运行以下命令安装
shx
:npm i -D shx
然后在
package.json
中重新定义你的clean
脚本如下:"scripts": { "clean": "shx rm -rf lib" }