使用包分发 NPM 脚本以供项目安装使用

Distributing NPM Scripts With A Package For Use By Project Installing It

我已经将我所有的 linting 配置和相关 packages/plugins/presets(对于 prettier、stylelint、eslint、commitlint)移到了一个 npm 包中。然后我在多个项目中使用这个包,并将配置扩展或合并到项目的本地配置文件中,以确保一致性并消除安装和保持我的开发依赖项最新的需要。

除了配置之外,我还有许多有用的 npm 脚本,它们 运行 代码检查并执行各种其他与开发相关的功能,例如:

"lint:prettier": "prettier 'src/**/*.{js,json}' --write",
"lint:eslint": "eslint 'src/**/*.js'",
"lint:compatibilityCheck": "eslint --print-config .eslintrc.js | eslint-config-prettier-check",
"lint": "npm run lint:compatibilityCheck && npm run lint:prettier && npm run lint:eslint"

这些目前在我的所有项目中都是重复的,但我想将这些脚本与我的共享包一起分发,以便将它们定义在一个位置。我应该怎么做?

我不确定尝试允许依赖项更改依赖项配置是否正确,即使我知道一个简单的方法来做到这一点。

与其尝试从下到上,不如反过来。我极力推荐使用 lerna

这是在 monorepo 中管理包的一个很好的工具,你甚至可以在你的包之间提升共享的依赖关系,对于你的问题,它允许在你所有的包之上定义,一个主要的 package.json 其中您可以只定义一次 npm scripts,并使用单个命令为所有包(或只有少数使用 scope 功能的包)定义 运行。

npm blog看来,似乎没有"direct ways"在npm包中公开开发脚本。博客 post 建议使用 shelljs 模块创建 运行 您首选脚本的 JavaScripts 文件。

示例:假设您要公开 lint:prettier": "prettier 'src/**/*.{js,json}' --write"

将调用包装在 bin/lintprettier.js:

#! /usr/bin/env node
var shell = require("shelljs");
const path = require("path")

process.env.PATH += (path.delimiter + path.join(process.cwd(), 'node_modules', '.bin'));
shell.exec("prettier 'src/**/*.{js,json}' --write");

然后将其添加到 package.json:

中导出的控制台脚本
...
"bin": {
   "lint-prettier": "bin/lintprettier.js"
}
...

最后,您可以在您的项目中重复使用您的脚本:

"scripts": {
   "build": "...",
   "lint:prettier": "lint-prettier"
 }

一种方法是使用 Builder

Builder 允许您将 npm 脚本作为 NPM 包发送,并且 运行 在您安装了包含脚本的包的任何项目中。

在我的用例中,我将所有 build/test/lint 脚本放在一个 NPM 包中,然后我在所有其他项目中安装这个包。然后在每个项目中我可以 运行 完全相同的命令。

Builder 最近没有得到很好的维护,但它相当稳定,我使用它并取得了很大的成功。自述文件非常详尽,几乎描述了您需要了解的所有内容。

Cristiano 的回答也很好,因为采用这种方法可以让您更好地控制解决方案的实施,而使用 Builder 它是另一个项目,有自己的实施(而且问题很少)。

我做了一个工具来解决这类问题。我称之为Dictator Builder。它有助于创建自己的 NPM 包的独裁者。

独裁者可以配置为指示 scripts 应该在 package.json 中,还可以提供任何其他需要的配置文件:

{
  "message": "Setup package.json and linting",
  "actions": [
    {
      "message": "Should have lint script in package.json",
      "haveJsonPathValues": [
        {
          "expression": "$.scripts.lint",
          "value": "npm run eslint"
        }
      ],
      "target": "package.json"
    },
    {
      "copyFrom": "static-files",
      "target": "."
    }
  ]
}