如何在 lerna monorepo 中使用 lint-staged 来 运行 所有包中的相同命令?
How to use lint-staged in a lerna monorepo to run the same command in all packages?
我有以下根 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 模块,我的问题是,如何设置它以便我目前的命令仍然 运行 但仅在暂存文件上没有在每个项目中安装命令的所有依赖项?测试命令也可能是一个问题,因为它在每个项目中 运行s tsc --noEmit
,我可以强制它也只检查暂存文件吗?
对此有一个替代解决方案,因为截至目前,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;"
}
您可能希望将 lint-staged
安装在当前正在开发的那些包中,而不是在您的根项目中。
意见:
One package may be typescript based, while others may be still flow based, for instance, so you definitely don't want your setting files to be on your root project.
假设您有两个包裹:
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
上安装 eslint
、prettier
或两者(不在根项目中)。
$ npx lerna add --dev eslint --scope=@my-abc/app-abc
The configuration file above tells lint-staged
to run eslint --fix
against each file that has been staged inside that package.
这种方法允许您为不同的包创建单独的 .eslintrc.js
或 .prettierrc
文件,其中包含不同的 linting 或 prettier 设置。
如果您在项目根目录中安装了 lint-staged
、eslint
、prettier
等,对于每个暂存文件,您的 git 钩子(或 husky)将可能 运行 eslint --fix
在不同的包上使用相同的设置,可能有非常具体的环境要求。您的 .eslintrc.js
可能会很乱并且充满了覆盖。
结论
所以在你的包中安装 lint-staged
之后,你希望你的 git 钩子(或 husky)到 运行 以下带有 lerna 的命令行:
npx lerna run lint-staged
现在您仍然需要将此脚本添加到您想要的软件包的 package.json 文件中。
{
...
scripts: {
...
"lint-staged": "lint-staged",
...
}
...
}
因此 lerna 将 运行 脚本 lint-staged
在所有具有脚本 lint-staged
的包上添加到 package.json 文件的 scripts
条目中。
我有以下根 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 模块,我的问题是,如何设置它以便我目前的命令仍然 运行 但仅在暂存文件上没有在每个项目中安装命令的所有依赖项?测试命令也可能是一个问题,因为它在每个项目中 运行s tsc --noEmit
,我可以强制它也只检查暂存文件吗?
对此有一个替代解决方案,因为截至目前,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;"
}
您可能希望将 lint-staged
安装在当前正在开发的那些包中,而不是在您的根项目中。
意见:
One package may be typescript based, while others may be still flow based, for instance, so you definitely don't want your setting files to be on your root project.
假设您有两个包裹:
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
上安装 eslint
、prettier
或两者(不在根项目中)。
$ npx lerna add --dev eslint --scope=@my-abc/app-abc
The configuration file above tells
lint-staged
to runeslint --fix
against each file that has been staged inside that package.
这种方法允许您为不同的包创建单独的 .eslintrc.js
或 .prettierrc
文件,其中包含不同的 linting 或 prettier 设置。
如果您在项目根目录中安装了 lint-staged
、eslint
、prettier
等,对于每个暂存文件,您的 git 钩子(或 husky)将可能 运行 eslint --fix
在不同的包上使用相同的设置,可能有非常具体的环境要求。您的 .eslintrc.js
可能会很乱并且充满了覆盖。
结论
所以在你的包中安装 lint-staged
之后,你希望你的 git 钩子(或 husky)到 运行 以下带有 lerna 的命令行:
npx lerna run lint-staged
现在您仍然需要将此脚本添加到您想要的软件包的 package.json 文件中。
{
...
scripts: {
...
"lint-staged": "lint-staged",
...
}
...
}
因此 lerna 将 运行 脚本 lint-staged
在所有具有脚本 lint-staged
的包上添加到 package.json 文件的 scripts
条目中。