【问题标题】:How to use lint-staged in a lerna monorepo to run the same command in all packages?如何在 lerna monorepo 中使用 lint-staged 在所有包中运行相同的命令?
【发布时间】:2020-10-25 00:08:57
【问题描述】:

我有以下根 package.json:

{
  "name": "project",
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "scripts": {
    "build": "lerna run build",
    "dev": "lerna run start --stream --parallel",
    "format": "yarn prettier --write",
    "prettier": "prettier --ignore-path .gitignore \"**/*.+(ts|tsx|json)\"",
    "test": "lerna run test --"
  },
  "husky": {
    "hooks": {
      "pre-commit": "yarn format && yarn test"
    }
  },
  "devDependencies": {
    "husky": "^4.2.5",
    "lerna": "^3.22.1",
    "prettier": "^2.0.5"
  }
}

问题是使用此设置,当我仍在处理文件时无法提交,要解决此问题,我可以使用 lint-staged 模块,我的问题是,如何设置它以便命令我目前仍在运行,但仅在暂存文件上运行,而没有在每个项目中安装命令的所有依赖项? test 命令也可能是个问题,因为它在每个项目中都运行tsc --noEmit,我可以强制它也只检查暂存文件吗?

【问题讨论】:

    标签: tsc lerna monorepo lint-staged


    【解决方案1】:

    对此有一个替代解决方案,因为截至目前,lint-staged 不能很好地与 lerna 命令进行测试。

    解决方案涉及使用package.json 中的git 命令来存储未跟踪且未暂存的文件,执行测试,然后在测试后重新实现未跟踪和未暂存的文件。

    此方法的一个例外是 git 将文件更改视为需要手动合并的合并冲突。

    以下是要进行的更改:

    文件: ./package.json

    {
      "name": "project",
      "private": true,
      "workspaces": [
        "packages/*"
      ],
      "scripts": {
        "build": "lerna run build",
        "dev": "lerna run start --stream --parallel",
        "format": "yarn prettier --write",
        "prettier": "prettier --ignore-path .gitignore \"**/*.+(ts|tsx|json)\"",
        "test": "lerna run test",
        "test:staged": "git stash -k --include-untracked; yarn test; git stash apply;"
      },
      "lint-staged": {
        "packages/**/*.{ts,js,json,md}": [
          "prettier --write"
        ]
      },
      "husky": {
        "hooks": {
          "pre-commit": "yarn format && yarn test:staged"
        }
      },
      "devDependencies": {
        "husky": "^4.2.5",
        "lerna": "^3.22.1",
        "prettier": "^2.0.5"
      }
    }
    

    更具体地说,这一行:

    {
       "test:staged": "git stash -k --include-untracked; yarn test; git stash apply;"
    }
    

    【讨论】:

      【解决方案2】:

      您可能希望将lint-staged 安装在当前正在开发的那些包中,而不是您的根项目中。

      意见:

      例如,一个包可能是基于 typescript 的,而其他包可能仍然是基于流的,因此您绝对不希望您的设置文件位于根项目中

      假设你有两个包:

      packages/
        shared-abc
        app-abc
      

      您需要在您和您的团队正在开发的软件包上安装 lint-staged

      $ npx lerna add --dev lint-staged --scope=@my-abc/app-abc
      

      然后在你安装的包lint-staged上你要定义配置文件.lintstagedrc,例如:

      {
        "*.{js,jsx,ts,tsx}": ["eslint --fix"]
      }
      

      顺便说一句,您可能还想在每个 lerna package 上安装 eslintprettier 或两者(不在根项目中)。

      $ npx lerna add --dev eslint --scope=@my-abc/app-abc
      

      上面的配置文件告诉lint-staged 运行eslint --fix已在该包中暂存的每个文件

      这种方法允许您拥有单独的 .eslintrc.js.prettierrc 文件,并为您的不同软件包提供不同的 linting 或更漂亮的设置。

      如果您在项目根目录中安装了lint-stagedeslintprettier 等,对于每个暂存文件,您的 git hook(或 husky)可能会在不同的包上以相同的设置运行eslint --fix可能有非常具体的环境要求。你的.eslintrc.js 可能会很乱,而且充满了覆盖。

      结论

      所以在你的包中安装 lint-staged 之后,你希望你的 git hook(或 husky)使用 lerna 运行以下命令行:

      npx lerna run lint-staged
      

      现在您仍然需要将此脚本添加到所需包的 package.json 文件中。

      {
      ...
      scripts: {
         ...
         "lint-staged": "lint-staged",      
         ...
      }
      ...
      }
      

      因此 lerna 将对所有将脚本 lint-staged 添加到其 package.json 文件中的 scripts 条目的包运行脚本 lint-staged

      【讨论】:

        猜你喜欢
        • 2020-09-20
        • 2021-05-24
        • 2020-08-18
        • 2019-09-20
        • 2020-07-30
        • 2019-08-14
        • 2019-09-12
        • 2018-10-07
        • 2018-09-14
        相关资源
        最近更新 更多