浅谈 husky 原理
最近在搭建新工程时,想给工程配置 eslint 约定一下代码规范,配置完 eslint 之后,有想着可以更进一步配置一个强校验,即不符合 eslint 配置的代码,希望在代码提交时就拦截并给出提示。面对这个场景自然而然就想到了 husky + lint-staged
的配置,说干就干。
- 首先是安装依赖,在工程根目录下执行以下命令:
1 | npm i husky lint-staged -g |
- 接着安装以往经验就是在
package.json
里配置相关配置:
1 | { |
最近在搭建新工程时,想给工程配置 eslint 约定一下代码规范,配置完 eslint 之后,有想着可以更进一步配置一个强校验,即不符合 eslint 配置的代码,希望在代码提交时就拦截并给出提示。面对这个场景自然而然就想到了 husky + lint-staged
的配置,说干就干。
1 | npm i husky lint-staged -g |
package.json
里配置相关配置:1 | { |
随着业务的发展,monorepo 工程越来越大~
git commit
时耗时会比较久,耗时是大概 1min+;git merge release
分支时耗时会更久,常常是 5min+;根据以往的工作经验,在没有用 ts 的工程里 lint 执行都是比较快的,所以这里猜想是 ts 的某些 rule 影响了整体的执行速度,终于在 typescript-eslint 找到了原因:Troubleshooting & FAQs | TypeScript ESLint
如果我们在工程里开启了type-aware lint,那么执行 lint 的时间将会和构建时间一样长。
typescript-eslint 的一些 rules 是依赖 type information,所以在执行 lint 前会先编译一遍ts
Linting with Type Information | TypeScript ESLint 官网这里具体描述了type-aware 是如何开启的:
parserOptions
(tsconfigRoot、project)type-aware
相关 rules业务发展了一年多,随着工程越来越大,发现在提交代码的时候,耗时会很久。最近在业务需求不是很紧的时候,就抽空研究了一下。
在提交代码的时候,触发了 husky 配置的 pre-commit
的 git hooks。相信大家对于这个 git hook 不会很陌生,我们大部分需要团队合作的项目,为了约束大家的代码规范,通常会选择使用 husky 并且在提交前进行代码校验拦截,这个时机就刚好是 pre-commit
git hooks 的时机。
所以问题一下就变得清晰起来,是 pre-commit 的 hook 执行的 lint 检查耗时过长。首先先介绍下我们工程的技术选型:yarn + learn + ts + react ,在正式排查前,猜测主要导致 lint 执行慢的因素大概有两个 monorepo(工程多、代码量大)、ts(ts 类型检查耗时)。
在开始排查问题之前,先做了个小测试:只改动了一个 tsx 文件,并尝试提交,计时发现,从开始 commit 到 commit 完成,发现竟然耗时了 1min+,晕~。这里就猜想会不会是某个 lint 规则 或 某个 lint 插件导致运行很慢的?接下来就沿着这个思路进行排查。
最近在鼓捣 eslint 规则配置的时候,有两个配置一直傻傻分不清,这两个配置就是 extends
和 plugins
。相信大家在实践过程中也会遇到这样的困扰,今天就来一起看一看,彻底搞清楚。
首先,我们知道 eslint 是一个代码检查工具,它会根据我们在工程里配置的规则,来进行校验。我们常常在以下场景中使用到 eslint。
所以一个团队如果想要保持统一的代码风格、良好的编码习惯,那约定和制定自己的 lint 规则就显得很重要。
在简单的场景中,我们可以不需要了解 plugins 和 extends 的概念,比如只是约定「封号」、「引号」的使用:
1 | { |
通过这样的配置,就约定了工程里统一强制使用封号结尾和双引号。
然而渐渐的,eslint 默认的一些规则不再满足我们的需要,这时我们就需要引入更多的规则集,这就是 plugins 的概念。
最近在 React 项目中引入 @loadable/component
进行懒加载优化时,发现了一个样式优先级问题。
我们工程里使用的是公司内部组件库,在想要覆盖组件库组件的样式时,基于 styled-components
的写法如下:
1 | import styled from 'styled-components'; |
正常情况下,上述代码应该会生效,即最终展现在页面上的按钮样式宽度应该是 80 px,高度为 32 px,覆盖原 Button 组件的宽高样式。
但是在实际使用过程中,我们发现了一些异常:覆盖的样式会偶现失效的情况。有些时候自定义宽高会生效,有些时候自定义宽高不会生效。经过排查,发现如果是在CustomButton
所在页面刷新,则按钮展示的宽高是符合预期的,如果是从其他页面进入的,则自定义宽高不会生效。没有生效的原因也很简单,CustomButton
的样式优先级排在了 Button
后面。
Yarn 支持在工程的 package.json 文件中的 resolutions
字段里指定包的特定版本或者版本范围。
总的来说就是,我们希望指定工程直接依赖里的某个子依赖包的版本时,可以使用
resolutions