如何只在我想要提交的文件上运行 Prettier?

Posted

技术标签:

【中文标题】如何只在我想要提交的文件上运行 Prettier?【英文标题】:How Do I Run Prettier Only on Files That I Want to Commit? 【发布时间】:2018-05-16 13:14:54 【问题描述】:

使用Husky,我使用预提交挂钩设置了我的package.json,以便在每次提交之前使用Prettier 格式化我的javascript 代码:


  "name": "prettier-demo",
  "scripts": 
    "precommit": "prettier --write **/*.js && git add ."
  ,
  "devDependencies": 
    "husky": "^0.14.3",
    "prettier": "^1.8.2"
  

这很好用,但有两个缺点:

    如果我有一个包含数千个 JavaScript 文件的大型项目,我必须等待 Prettier 处理所有这些文件,即使只有少数发生了更改;这可能需要很长时间,并且每次提交完成后都会很快让我感到紧张

    有时我只想暂存几个文件以进行提交,而将其他更改排除在提交之外;因为我在运行 Prettier 后做了一个git add .,所以我所有的更改都将始终在提交中结束

如何在每次提交之前只在已暂存的文件上运行 Prettier,而忽略未暂存或未更改的文件?

【问题讨论】:

【参考方案1】:

您可以使用lint-staged:

在提交代码之前运行时,Linting 更有意义。通过这样做,您可以确保没有错误进入存储库并强制执行代码样式。但是在整个项目上运行 lint 过程很慢,并且 lint 结果可能无关紧要。最终,您只想对将要提交的文件进行 lint。

此项目包含一个脚本,该脚本将运行任意 npm 和 shell 任务,其中包含一个暂存文件列表作为参数,由指定的 glob 模式过滤。

使用以下命令安装 lint-stagedhusky,这是 pre-commit 挂钩所必需的:

npm install --save-dev lint-staged husky

如下更改你的 package.json:


  "scripts": 
    "precommit": "lint-staged"
  ,
  "lint-staged": 
    "*.js": [
      "prettier --write",
      "git add"
    ]
  

【讨论】:

@PatrickHund 我同意,但我也喜欢你亲力亲为的态度 :) 如果你愿意,你仍然可以取消删除你的答案。 不,没关系。我团队的另一位开发人员实际上已经使用 lint-staged 设置了预提交,但它不能正常工作,因为他输入了“git add”。在配置中而不是“git add”。所以我写了那个 bash 脚本,本来可以删除点并完成它? 我用 prettier-eslint 做到了这一点,与答案完全相同的语法。 "lint-staged": "*.js,less,json": [ "prettier-eslint --write", "git add" ] , 我还看到了一个“精确提交”repo,指出它只美化了文件暂存的部分,即暂存的大块而不是整个文件。你怎么看待这件事?我还没试过。 github.com/nrwl/precise-commits @AmirEldor 我认为这是个坏主意,因为这可能导致单个文件中的格式不一致。【参考方案2】:

我发现只是在运行:

prettier --write $(git diff --name-only --diff-filter d | grep '\.js$' | xargs)

对我的需要来说已经足够了,只是做了一个别名并使用它。

【讨论】:

实际上返回了一些路径中包含 .js 的结果。这对我来说效果更好: git diff --name-only | grep '\.ts$' 我也刚刚了解到删除文件时这将失败。 Prettier 将尝试格式化删除的文件。要使其正常工作,请使用prettier --write $(git diff --name-only --diff-filter d | grep '\.ts$' | xargs) 感谢@NitsanBaleli 我更新了消息以包含您的 grep 匹配修复并过滤已删除的修复!【参考方案3】:

如果您不想添加 devDependency lint-staged,您也可以使用 Bash 脚本执行相同操作:

#!/usr/bin/env bash
# chmod +x this and save in your PATH. Assumes `prettier` is in your `devDependencies` already
BASE=$(git merge-base master HEAD) # change master to whatever your trunk branch is
FILES=$(git diff --name-only $BASE HEAD | xargs)

npx prettier --list-different $FILES

# Want eslint too?
# npx eslint --ignore-path=.prettierignore $FILES

【讨论】:

【参考方案4】:

我用这个包pretty-quick

在我的package.json添加添加脚本

"pretty-quick": "pretty-quick" 

scripts

然后在我的pre-commit钩下.husky/pre-commit

我添加

npm run pretty-quick

【讨论】:

以上是关于如何只在我想要提交的文件上运行 Prettier?的主要内容,如果未能解决你的问题,请参考以下文章

更漂亮:仅针对文件的更改行运行

项目创建——代码规范prettier, commitlint

如何更改 .less 文件的 Prettier 行为?

如何在“codesandbox.io”上配置 ESLint / Prettier 格式规则

为 HTML 文件配置 Prettier

VSCode Prettier 没有格式化 PHP