首页 > 解决方案 > NPM 条件脚本(Windows / Mac)应执行不同的命令)

问题描述

用例:

prepublishOnly在 NPM 中设置了一个钩子,它删除“lib”文件夹,然后将 typescript 源文件转换为新的 lib 文件夹,然后运行测试。

问题:

两个人应该发布 NPM 包,他们都在不同的操作系统(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 脚本(基于使用的操作系统)或者是否有一个删除文件夹命令可以跨这些操作系统工作?

标签: typescriptnpmnpm-scripts

解决方案


如果您只想通过 npm 脚本以跨平台的方式删除文件夹,那么将gulp添加到您的工具列表中似乎是不必要的。对于轻量级解决方案,请考虑以下两种解决方案:


解决方案 1

看看rimraf,它被描述为:

rm -rf用于节点的 UNIX 命令。

用法

  1. cd到您的项目目录并运行以下命令:

    npm install rimraf --save-dev
    
  2. clean将您的脚本更改package.json为以下内容:

    "scripts": {
      "clean": "rimraf lib",
      ...
    },
    
  3. clean:windows从您的脚本中删除,package.json因为这现在是多余的。

请注意,在将其安装为本地依赖项时,我并没有取得很大的成功,因此我使用下面的解决方案二。但是,您可能会取得更大的成功 - 所以值得一试。


解决方案 2

以下解决方案使用shelljs rm类似于 Unixrm -rf命令的命令,除了它是用于节点的 - 因此它是一个跨平台的等价物。

以下步骤显示了如何实现这一点:

  1. cd到您的项目目录并通过运行以下命令安装shelljs :

    npm install shelljs --save-dev
    
  2. 创建一个自定义节点脚本如下,让我们命名文件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
    │   └── ...
    └── ...
    
  3. 将您的clean脚本替换package.json为以下内容:

    "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",
      ...
    },
    
  4. clean:windows从您的脚本中删除,package.json因为这现在是多余的。

笔记

  1. clean.js在调用脚本时,利用内置节点process.argv获取传递给 Node 的命令行参数数组。

  2. 然后我们slice()来自索引的参数数组,2以确保我们只包含文件夹/文件路径参数(例如lib)。

  3. 最后,我们循环使用数组中的每个文件夹路径,forEach()并在循环的每一轮中调用shell.rm('-rf', _path);以删除资产。


编辑/更新:

另一种跨平台解决方案(最初发布此答案时不可用)是利用shx包,它被描述为:

shxShellJS Unix 命令的包装器,为 npm 包脚本中的简单的类 Unix、跨平台命令提供简单的解决方案

  1. 运行以下命令进行安装shx

    npm i -D shx
    
  2. 然后重新定义您的clean脚本,package.json如下所示:

    "scripts": {
      "clean": "shx rm -rf lib"
    }
    

推荐阅读