在前端项目开发中, 开发style因人而异, 为了让team的code面对所有开发人员可维护, 可读, 最好的方法是使用linter. Linter 可以统一team代码规范, 检测潜在的bugs, 性能问题等. precommit是git的一个钩子, 它能让你在提交代码之前干点事, 今天就demo一下如何在一个项目里使用这些tools.编辑工具统一为vscode.
1, 什么是linter?
说白了就是一个帮你分析程序代码, 检测程序中潜在的输入错误工具. 它能帮开发快速的定位错误, 提示如何改正等. 现在js社区最流行的linter是Prettier和Eslint.
2,创建项目
找个空旷的目录, 执行:
npx create-react-app eslint-app cd eslint-app npm start
3,安装eslint
npm install eslint --save-dev # or yarn add eslint --dev
初始化eslint
npx eslint --init
按照上面的选择会生成一个.eslintrc.json在项目根目录,内容如下
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"plugin:react/recommended",
"airbnb"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 11,
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
}
}
如果想覆盖 Airbnb规则在在rules里面添加rule就行. 传送Eslint Rules.
4, 安装Prettier
作为vscode的一般插件安装就好了.
安装好之后在terminal执行命令把这几个包装上
npm i prettier eslint-config-prettier eslint-plugin-prettier -D
然后更新.eslintrc文件的extends如下:
"extends": [ "airbnb", "plugin:prettier/recommended" ]
如果不想用Prettier的配置, 可以在根目录新建一个名为.prettierrc的文件, 配置自己的配置.
{
"root": true,
"printWidth": 120,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"endOfLine": "lf",
"singleQuote": false,
"jsxSingleQuote": false,
"semi": true,
"parser": "typescript"
}
5, 让vscode每次format code当保存文件的时候
打开vscode的setting配置 添加如下配置
{
"workbench.iconTheme": "vscode-icons",
"editor.fontSize": 16,
"editor.formatOnPaste": false,
"[javascript]": {},
"files.associations": {
"*.js": "javascriptreact",
"*.wxss": "css",
"*.wxml": "html"
},
"eslint.lintTask.enable": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
],
"javascript.updateImportsOnFileMove.enabled": "always",
"search.exclude": {
"**/node_modules": false
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"window.zoomLevel": 0
}
这样基本的配置就算完成了, 可以检查代码的格式, 一般性的代码错误了
6, 设置Husky pre-commit hook
这一步看似是没什么必要, 因为每次format的时候已经改了, 可能有些人懒得改设置了disable, 就当再上个保险吧.
(1), 什么是Husky?
Husky让我们在git commit和push之前能运行一些命令.
(2), 什么是lint-staged?
lint-staged 能让我们在git staged状态的文件上跑多个linter, 在这跑的就是Eslint和Prettier.
下面就说说怎么用husky
先安装几个必要的包
使用 npm
npm install --save-dev husky lint-staged eslint eslint-config-airbnb prettier
使用 yarn
yarn add --dev husky lint-staged eslint eslint-config-airbnb prettier
打开package.json, 和dependencies同级添加如下配置:
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"./src/*.{js,jsx,ts,tsx}": [
"npm run lint:js",
"npx prettier --write",
"eslint src/*.js --fix-dry-run",
"git add"
],
"**/*.less": [
"stylelint --syntax less",
"npm run prettier",
"git add"
]
},
上面的code会对所有的js,jsx,ts,tsx文件跑一遍Prettier and ESLint rules, 当然这个正则可以修改为自己想匹配了跑的.
添加了上面配置, 如果有eslint报错就没法成功提交, 这样我们统一代码规范的目的就达到了.
最后贴上我的配置:
VsCode:
{
"workbench.iconTheme": "vscode-icons",
"editor.fontSize": 16,
"editor.formatOnPaste": false,
"[javascript]": {},
"files.associations": {
"*.js": "javascriptreact",
"*.wxss": "css",
"*.wxml": "html"
},
"eslint.lintTask.enable": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
],
"javascript.updateImportsOnFileMove.enabled": "always",
"search.exclude": {
"**/node_modules": false
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": true,
"typescript.updateImportsOnFileMove.enabled": "always",
"window.zoomLevel": 0
}
Eslint:
{
"env": {
"browser": true,
"es6": true
},
"extends": [ "plugin:prettier/recommended", "airbnb"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 11,
"sourceType": "module"
},
"plugins": [ "react"],
"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [ ".js", ".jsx"]
}
],
/**
"always" enforces braces around the function body
"as-needed" enforces no braces where they can be omitted (default)
"never" enforces no braces around the function body (constrains arrow functions to the role of returning an expression)
*/
"arrow-body-style": [ "error", "as-needed"],
/**
"properties": "always" (default) enforces camelcase style for property names
"properties": "never" does not check property names
"ignoreDestructuring": false (default) enforces camelcase style for destructured identifiers
"ignoreDestructuring": true does not check destructured identifiers (but still checks any use of those identifiers later in the code)
"ignoreImports": false (default) enforces camelcase style for ES2015 imports
"ignoreImports": true does not check ES2015 imports (but still checks any use of the imports later in the code except function arguments)
allow (string[]) list of properties to accept. Accept regex.
*/
"camelcase": [ "error", "never"],
"no-param-reassign":[ "error", { "props": false }],
// "allowForLoopAfterthoughts": true allows unary operators ++ and -- in the afterthought (final expression) of a for loop.
"allowForLoopAfterthoughts":[ "error", { "allowForLoopAfterthoughts": true }],
"prefer-template":[ "error"],
"no-use-before-define": [ "error", { "functions": true, "classes": true }]
}
}
Prettier:
{
"root": true,
"printWidth": 120,
"trailingComma": "all",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"jsxBrackets": true,
"endOfLine": "lf",
"singleQuote": true,
"jsxSingleQuote": false,
"semi": true,
"parser": "typescript"
}
-- end --