关键词: lint-staged、husky、commitlint、eslint、stylelint、prettier、commitlint
这些是我们日常生活中必不可可少的,有些是框架就帮你做好了,你可能不知道在precommit之前都做了什么
如何避免每次新建项目拷贝eslint、stylelint、preitter等规则,建立一个预设或extends?
eslint规则为什么老是和preitter规则冲突?
如何自己写一个plugins?
husky
第一步安装husky
它是一个git hook,husky支持的git hooks,常用的是 pre-commit、commit-msg
js
// 1. Install `husky`
npm install husky --save-dev
// 2. Enable Git hooks
npx husky install
// 3. 在package.json的scripts 下面添加
"prepare": "husky install" // yarn2+ 不支持,用postinstall
第二步创建hook
js
// 创建pre-commit hooks并且添加脚本,这个脚本的内容根据使用的工具会有所区别,但意思就是在我commit之前使用lint-staged帮我校验一些东西,比如eslint、stylelint等修复
npx husky add .husky/pre-commit "npx --no-install lint-staged --quiet"
//创建commit-msg,使用commitlint规范commit msg
npx husky add .husky/commit-msg "npx -r exec commitlint --edit $1"
npx --no-install lint-staged究竟是什么意思,pnpm 中是怎么配置,lerna呢
-
--no-install 是npx的参数,不要安装缺少的依赖,而是从本地中安装
-
--quiet 安装期间禁止输出详细信息,只输出关键结果
-
--edit 以在交互模式下编辑提交信息
注意点
4升级到8这是一个大的break change,由之前的.huskyrc json文件变成.huskyrc/commit-msg
lint-staged
在commit 之前,可以自动prettier、eslint、stylelint等
下面逐一分析eslint、stylelint、prettier
js
// 一个简单package.json lint-staged相关的配置的实力
{
"**/*.{js,jsx,tsx,ts,less,scss,md,json}": [
"prettier --cache --write"
],
"*.{js,jsx,ts,tsx}": [
"elintint --fix ",
],
"*.{css,less}": [
"stylelint --fix",
],
"lint-staged": {
"**/*.less": "pnpm lint:style --fix",
"**/*.{js,jsx,ts,tsx}": "pnpm lint:js --fix",
"**/*.{js,jsx,tsx,ts,less,scss,md,json}": [
"prettier --write"
]
}
eslint
注意,配置文件的优先级,降序排列,其他的配置文件也是类似的顺序
.eslintrc.js
.eslintrc.cjs
.eslintrc.yaml
.eslintrc.yml
.eslintrc.json
package.json
eslint参数
参数配置太多,咱们就是挑重点的讲
parser
js
import @typescript-eslint/parser from "@typescript-eslint/parser";
{
parser: require.resolve('@typescript-eslint/parser'),
plugins: ['@typescript-eslint/eslint-plugin'],
files: ['**/*.{ts,tsx}'],
parseroptions:{
ecmaFeatures: {
jsx: true
}
}
}
总共也就是三个parser
- Esprima
- @babel/eslint-parser - es 兼容eslint
- @typescript-eslint/parser ts转为eslint
plugins
js
module.exports = {
extends: [
'plugin:react/recommended'
],
plugins: ['react'], // 安装依赖会是 eslint-plugin-react
rules:{
// 通常规则都是会以react/xx开头
'react/jsx-uses-react': 'error',
'react/jsx-uses-vars': 'error',
'react/xxx'
}
processor
处理器允许ESLint将文本转换成ESLint可以检测的代码片段。
js
import markdown from "eslint-plugin-markdown";
export default [
{
files: ["**/*.md"],
plugins: {
markdown
},
processor: "markdown/markdown",
settings: {
sharedData: "Hello"
}
}
];
settings
如果在settings下设置参数,则会应用于每一个规则
css
settings: {
react: {
version: 'detect',
},
},
rules
这可以不用多说,就是就是各种各样的eslint规则。有一点注意: off-0 是关闭规则,warn-1是警告,error-2 打开规则
languageOptions
js
export default [
{
files: ["**/*.js"],
languageOptions: {
ecmaVersion: 5
}
}
];
- ecmaVersion: 配置JavaScript类型
参数有"module"
, "commonjs"
, or "script"
, 默认是 module
- parser: 自定义parser
js
// 覆盖默认的parser ,注意parser 和parserOptions可以不用写在languageOptions里面
import babelParser from "@babel/eslint-parser";
export default [
{
files: ["**/*.js", "**/*.mjs"],
languageOptions: {
parser: babelParser,
parserOptions: {
requireConfigFile: false,
babelOptions: {
babelrc: false,
configFile: false,
// your babel options
presets: ["@babel/preset-env"],
}
}
}
}
];
- globals: 设置全局变量
css
globals: {
NodeJS: 'writable/readable',
JSX: 'writable/readable',
Formily: 'writable/readable'
},
📢注意: 有些地方配置是false === readable ===readonly ,true === writeable === writable
其实更推荐这么用, 因为eslint 不会预定义, 推荐globals这个包
python
import globals from "globals";
export default [
{
languageOptions: {
globals: {
...globals.browser
}
}
}
];
eslint配置示例
这是一个支持ts的react版本简单实例
js
pnpm add eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-react -D
然后使用pnpm eslint --init,根据提示选择
就会得到这样一份初始文件
js
// .eslintrc.js
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
],
"overrides": [
{
"env": {
"node": true
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": "script"
}
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint", // @typescript-eslint/eslint-plugin
"react" // eslint-plugin-react
],
"rules": {
}
}
};
ts支持
主要是安装了@typescript-eslint/parser
和@typescript-eslint/eslint-plugin
,
@typescript-eslint/parser
解析ts代码,否则eslint不认识,直接报错@typescript-eslint/eslint-plugin
在代码中,可以使用Typescipt-eslint规则,依赖于@typescript-eslint/parser
plugin:@typescript-eslint/recommended
你可能会好奇,为什么extends 和 plugin 名字奇奇怪怪的,让人有点蒙圈。 其实他们是有规则的
比如, plugins: ['react', '@typescript-eslint']的写法, plugins具体名字就是eslint-plugin-react
、@typescript-eslint/eslint-plugin
, extend 对应的名字是 plugin:react/recommond
、 plugin:@typescript-eslint/recommended
一般来说,plugins 和 extends 是成对出现的,当然可以只有extends. 比如官方提供的eslint:recommended
,还有非官方的airbnb
(对应的依赖是eslint-config-airbnb
)
所以你看到这张图还会蒙圈吗,是不是敏锐地发现plugins 少写了参数,但是这不影响, 对应的还是能被正确的安装
plugins: ['@typescript-eslint','react','react-hooks','preitter']
react 支持
eslint-plugin-react
plugin:react/recommended
stylelint
pnpm add stylelint stylelint-config-standard -D
js
stylelintrc.js
{
"extends": "stylelint-config-standard",
"rules": {
"property-no-vendor-prefix": [
true,
{
"severity": "warning"
}
]
},
customSyntax: require.resolve('postcss-less'),
overrides: [
{
files: ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'],
customSyntax: require.resolve('@stylelint/postcss-css-in-js'),
},
],
}
常用几个extend
熟悉customSyntax,在实际过程中经常冲突。我以为只要配置stylelint-config-standard
就好了,实际还有很多配合一起使用
prettier
arduino
npm install --save-dev prettier eslint-config-prettier
ignore
js
// ..prettierignore
node_modules
...
集成linter
preitter --write 和 preitter --check
- preitter --write 自动修复和eslint --fix差不多
- preitter --check 就是check
配置文件
ini
module.exports = { ...require("@company/prettier-config"), semi: false, };
- editortconfig
js
// 这里的配置会覆盖prettierrc, 所以最好不要重复
# Non-configurable Prettier behaviors
[*] charset = utf-8
insert_final_newline = true
# Caveat: Prettier won't trim trailing whitespace inside template strings, but your editor might. Prettier不会删除字符串模板的尾随空格,当时编辑器会
# trim_trailing_whitespace = true
# Configurable Prettier behaviors # (change these if your Prettier config differs)
# https://prettier.io/docs/en/options.html 有类似的参数
end_of_line = lf
indent_style = space
indent_size = 2
max_line_length = 80
所以笔记写到的时候,我忽然悟了。总是你本地代码格式化与团队的不一致,是不是因为这里
eslint、stylelint、preitter合集解决方案
有没有觉得eslint、stylelint、preitter 一套下来,配置的东西还是有点多,可以参考社区的解决方案fabric
commitlint
commit 规范,参考zhuanlan.zhihu.com/p/51894196
changelog
主要是开源库当中会用,具体后续补充
问题
1、如何自己写一个plugin?
TODO: 后续补充
2、熟悉常用的规则,如果是通用的,应该怎么封装起来
如果但是rules的话,直接抽成一个公用的文件;如果还有其他配置的话, 用extends
js
module.exports = {
extends: ['../../.eslintrc.js', 'plugin:react/jsx-runtime']
};
3、 为什么我们经常碰到因为配置器导致格式化不一致的问题?
TODO: 下篇接着写