最新发布《数智时代的AI人才粮仓模型解读白皮书(2024版)》,立即领取! 了解详情
写点什么

力荐!这些工具可以帮你写出干净的代码

  • 2018-12-24
  • 本文字数:7791 字

    阅读完需:约 26 分钟

力荐!这些工具可以帮你写出干净的代码

想写出好代码,却不知道从哪里开始?想删除死代码?想在代码库中找出未被使用的变量?想在代码中找出有问题的模式?


你是多元化团队的负责人吗?你的团队中有新来的开发人员吗?你担心他们会写出不符合标准的代码吗?在代码评审时是否花了一整天的时间去检查代码标准,而不是实际的逻辑实现?


我一直在做这样的事情,经常忙得像热锅上的蚂蚁。但从现在开始,我们要保证永远不再担心这类问题。在阅读本文过程中,如果遇到困难,可以参考代码库(https://github.com/adeelibr/react-starter-kit)。


本文更多地是针对 React 应用程序,但同样适用于其他 Web 项目。

让我们从 Prettier 开始吧

什么是 Prettier?


Prettier 是一种代码格式化程序,它以特定的方式为你格式化代码。


请看这个 GIF:



我们为什么需要 Prettier?


  • 清理现有代码库:通过单个命令行清理代码库。想象一下清理超过 20,000 行代码的代码库会是怎样的一种情景。

  • 易于适用:Prettier 在格式化代码时使用争议最少的编码风格。因为是开源的,很多人已经在修复一些边缘情况和优化体验方面进行了多次迭代。

  • 编写代码:人们没有意识到的是,他们花了很多时间用于格式化代码,这浪费了他们太多的精神能量。让 Prettier 来处理格式化的事情,开发人员就可以专注在核心业务逻辑上。Prettier 可以将效率提高 10%。

  • 帮助新手:如果你是一位与优秀工程师并肩工作的新手,并且你希望自己看起来很酷,可以写出干净的代码,那就使用 Prettier 吧。

如何设置 Prettier?

创建一个叫作 app 的文件夹,进入该文件夹,在命令行中敲入:


npm init -y
复制代码


这将在 app 文件夹中创建一个 package.json 文件。


我将在本文中使用 yarn,但你也可以使用 npm。


安装我们的第一个依赖项:


yarn add --dev prettier
复制代码


这将安装 package.json 中指定的开发依赖项,如下所示:


{  "name": "react-boiler-plate",  "version": "1.0.0",  "description": "A react boiler plate",  "main": "src/index.js",  "author": "Adeel Imran",  "license": "MIT",  "scripts": {    "prettier": "prettier --write src/**/*.js"  },  "devDependencies": {    "prettier": "^1.14.3"  }}
复制代码


稍后我会解释“prettier”: “prettier — write src/**/*.js”的作用,现在先让我们在 app 文件夹中创建一个 src/文件夹。在 src/文件夹中,再创建一个名为 index.js 的文件——名字可以随意起。


在 index.js 文件中,按原样粘贴这句话:


let person =                     {  name: "Yoda",                designation: 'Jedi Master '                };



function trainJedi (jediWarrion) {if (jediWarrion.name === 'Yoda') { console.log('No need! already trained');}console.log(`Training ${jediWarrion.name} complete`) }

trainJedi(person) trainJedi({ name: 'Adeel', designation: 'padawan' });
复制代码


到目前为止,我们有了一个 src/app/index.js 文件,包含了一些难看的代码。


我们可以做三件事:


  • 手动缩进并格式化代码;

  • 使用自动化工具;

  • 保持不变(请不要这么做)。


我打算选择第二项,所以我们安装了一个依赖项,并在 package.json 中声明了 Prettier。


现在在 app 根文件夹中创建一个 prettier.config.js 文件,并在其中添加一些 Prettier 规则:


module.exports = {  printWidth: 100,  singleQuote: true,  trailingComma: 'all',  bracketSpacing: true,  jsxBracketSameLine: false,  tabWidth: 2,  semi: true,};
复制代码


printWidth 将确保你的单行代码不会超过 100 个字符。


singleQuote 会将所有双引号转换为单引号。


trailingComma 将确保在最后一个对象属性的末尾会有一个逗号。


bracketSpacing 在对象字面量之间打印空格:


If bracketSpacing is true - Example: { foo: bar }If bracketSpacing is false - Example: {foo: bar}
复制代码


jsxBracketSameLine 将在多行 JSX 元素的最后一行放置>:


// true example<button  className="prettier-class"  id="prettier-id"  onClick={this.handleClick}>  Click Here</button>
// false example<button className="prettier-class" id="prettier-id" onClick={this.handleClick}> Click Here</button>
复制代码


tabWidth 指定单个缩进的空格数。


如果 semi 设置为 true,将在语句末尾加上;。


现在让我们来说说这个脚本的作用:


“prettier”: “prettier  — write src/**/*.js”
复制代码


它的意思是运行 prettier,并让它在 src/文件夹中查找所有的.js 文件。–write 标志告诉 prettier 要把格式化好的内容保存到文件中,并找出格式化过程中发现的任何异常。


现在在终端中运行这个脚本:


yarn prettier
复制代码


这是我在运行代码时看到的:


ESLint

什么是代码 linter?


代码 linting 是一种代码静态分析,通常被用于查找不符合某些样式指南的有问题的模式或代码。大多数编程语言都有代码 linting,编译器有时会在编译过程中加入 linting。

——来自 ESLint


为什么 JavaScript 需要 linter?


由于 JavaScript 是动态类型的,而且是一种松散类型的语言,因此开发人员在使用这门语言时很容易犯错。因为不经过编译,所以通常需要在执行.js 文件的情况下才能发现语法或其他错误。


像 ESLint 这样的 linting 工具可以帮助开发人员在不执行 JavaScript 代码的情况下发现问题。


是什么让 ESLint 如此特别?


ESLint 中的所有东西都是可插拔的,你甚至可以在运行时添加规则。你添加的每个 linting 规则都是独立的,任何一个规则都可以独自打开或关闭。每个规则都可以设置为警告或错误级别。


现在有 2 个流行的风格指南:



我一直在使用 Airbnb 的风格指南。这个风格指南一直有人在维护,在本文中,我将使用受 Airbnb 风格指南启发的规则集。


首先更新 package.json 文件:


{  "name": "react-boiler-plate",  "version": "1.0.0",  "description": "A react boiler plate",  "main": "src/index.js",  "author": "Adeel Imran",  "license": "MIT",  "scripts": {    "lint": "eslint --debug src/",    "lint:write": "eslint --debug src/ --fix",    "prettier": "prettier --write src/**/*.js"  },  "husky": {    "hooks": {      "pre-commit": "lint-staged"    }  },  "lint-staged": {    "*.(js|jsx)": ["npm run lint:write", "git add"]  },  "devDependencies": {    "babel-eslint": "^8.2.3",    "eslint": "^4.19.1",    "eslint-config-airbnb": "^17.0.0",    "eslint-config-jest-enzyme": "^6.0.2",    "eslint-plugin-babel": "^5.1.0",    "eslint-plugin-import": "^2.12.0",    "eslint-plugin-jest": "^21.18.0",    "eslint-plugin-jsx-a11y": "^6.0.3",    "eslint-plugin-prettier": "^2.6.0",    "eslint-plugin-react": "^7.9.1",    "husky": "^1.1.2",    "lint-staged": "^7.3.0",    "prettier": "^1.14.3"  }}
复制代码


在开始进行配置之前,先让我们来看看每个依赖包的功能。


babel-eslint:这个包让你可以轻松在 Babel 上使用 lint。如果你不使用 ESLint 尚不支持的 Flow 或实验性功能,则不一定需要这个插件。


eslint:这是 lint 代码所需的主要工具。


eslint-config-airbnb:这个包提供了所有 Airbnb 的 ESLint 配置,你可以修改它们。


eslint-plugin-babel:babel-eslint 的插件伴侣。


eslint-plugin-import:这个插件旨在支持 ES2015+(ES6+)的导入/导出语法,并防止出现拼写错误的文件路径和导入名称。


eslint-plugin-jsx-a11y:适用于 JSX 元素可访问性规则的 linting 规则。


eslint-plugin-prettier:让 ESLint 与 Prettier 的使用更顺畅。


eslint-plugin-react:特定于 React 的 linting 规则。


eslint-config-jest-enzyme:用于特定于 React 和 Enzyme 的全局变量。这个 lint 配置让 ESLint 知道有哪些全局变量,并且不会针对它们发出警告——有点像断言 it 和 describe。


eslint-plugin-jest:Jest 的 ESLint 插件。


husky:在自动化部分会进行更多介绍。


lint-staged:在自动化部分会进行更多介绍。


现在我们已经有了基本的了解,接下来可以开始了。


在 app/根目录创建.eslintrc.js 文件:


module.exports = {  env: {    es6: true,    browser: true,    node: true,  },  extends: ['airbnb', 'plugin:jest/recommended', 'jest-enzyme'],  plugins: [    'babel',    'import',    'jsx-a11y',    'react',    'prettier',  ],  parser: 'babel-eslint',  parserOptions: {    ecmaVersion: 6,    sourceType: 'module',    ecmaFeatures: {      jsx: true    }  },  rules: {    'linebreak-style': 'off', // Don't play nicely with Windows.    'arrow-parens': 'off', // Incompatible with prettier    'object-curly-newline': 'off', // Incompatible with prettier    'no-mixed-operators': 'off', // Incompatible with prettier    'arrow-body-style': 'off', // Not our taste?    'function-paren-newline': 'off', // Incompatible with prettier    'no-plusplus': 'off',    'space-before-function-paren': 0, // Incompatible with prettier    'max-len': ['error', 100, 2, { ignoreUrls: true, }], // airbnb is allowing some edge cases    'no-console': 'error', // airbnb is using warn    'no-alert': 'error', // airbnb is using warn    'no-param-reassign': 'off', // Not our taste?    "radix": "off", // parseInt, parseFloat radix turned off. Not my taste.    'react/require-default-props': 'off', // airbnb use error    'react/forbid-prop-types': 'off', // airbnb use error    'react/jsx-filename-extension': ['error', { extensions: ['.js'] }], // airbnb is using .jsx    'prefer-destructuring': 'off',    'react/no-find-dom-node': 'off', // I don't know    'react/no-did-mount-set-state': 'off',    'react/no-unused-prop-types': 'off', // Is still buggy    'react/jsx-one-expression-per-line': 'off',
"jsx-a11y/anchor-is-valid": ["error", { "components": ["Link"], "specialLink": ["to"] }], "jsx-a11y/label-has-for": [2, { "required": { "every": ["id"] } }], // for nested label htmlFor error
'prettier/prettier': ['error'], },};
复制代码


还要在 app/根目录中添加.eslintignore 文件:


/.git/.vscodenode_modules
复制代码


我们先介绍一下.eslintrc.js 文件的作用。


先把它拆分一下:


module.exports = {    env:{},    extends: {},    plugin: {},    parser: {},    parserOptions: {},    rules: {},};
复制代码


  • env:用于预定义全局变量。在我们的例子中,可用的环境包括 es6、browser 和 es6。es6 将启用除模块之外的所有 ECMAScript 6 功能。browser 将添加所有浏览器全局变量,如 Windows。node 将添加 Node 全局变量和 Node 作用域,比如 global。

  • extends:字符串数组——扩展了之面配置的额外配置选项。现在我们正在使用 airbnb 的 linting 规则,这些规则被扩展到 jest,然后是 jest-enzyme。

  • plugins:插件基本上就是我们想要使用的 linting 规则。现在我们正在使用 babel、import、jsx-a11y、react、prettier。

  • parser:默认情况下,ESLint 使用 Espree,但因为我们使用了 babel,我们还需要使用 Babel-ESLint。

  • parserOptions:如果我们将 Espree 的默认解析器更改为 babel-eslint,需要指定 parserOptions——它是必需的。我通过选项告诉 ESLint,ecmaVersion 是 6。因为我们在 EcmaScript 模块(而不是 script)中编写代码,所以我们将 sourceType 指定为 module。由于我们使用了 React,引入了 JSX,所以在 ecmaFeatures 中加了 jsx 选项,并将其设置为 true。

  • rules:我们已经扩展并通过插件添加的所有规则,我们可以更改或覆盖它们。

现在介绍一下.eslintignore。

.eslintignore 里包含了我们不希望 ESLint 对它们进行 lint 的路径列表。这里我只指定三个:


  • /.git——我不希望 Git 相关文件被 lint。

  • /.vscode——由于我使用的是 VS Code,这个编辑器提供了自己的配置文件,我不希望配置文件被 lint。

  • node_modules——我不希望依赖项被 lint,所以把这个目录也添加到列表中。


接下来让我们来看看 package.json 中新添加的脚本。


"lint": "eslint --debug src/""lint:write": "eslint --debug src/ --fix"
复制代码


  • $ yarn lint——运行这个命令,它将遍历 src/中的所有文件,并在每个找到错误的文件中提供详细日志,你可以手动打开这些文件并更正错误。



  • $ yarn lint:write——运行这个命令,它将执行与上述命令相同的操作。不同的地方在于,如果它可以纠正它发现的错误,它将纠正它们,并尝试从代码中尽可能多地移除代码坏气味。

让它更自动化一些

到目前为止,我们设置好了 prettier 和 eslint,但每次我们都要运行脚本。接下来我们让它更加自动化一些。


  • 在编辑器中按下 ctrl + s 时格式化和 lint 代码。

  • 每次提交代码时,自动对代码进行 lint 和格式化。


要在保存代码时进行格式化和 lint,需要使用像 VS Code 这样的编辑器:


安装 ESLint 扩展插件。在此(https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)下载插件或在 VS Code 编辑器中按下 ctrl + shift + x 打开扩展模块,搜索 eslint,将出现一系列插件。安装 Dirk Ba​​eumer 开发的那个。安装完成后,点击 reload 按钮重新启动编辑器。


安装好这个插件后,在 app/根文件夹中创建一个名为.vscode/的文件夹 ——不要忘了那个点号,这个非常重要。


在文件夹中创建一个 settings.json 文件,如下所示:


{  "editor.formatOnSave": false,  "eslint.autoFixOnSave": true,}
复制代码


  • editor.formatOnSave——我在这里将它设置为 false,因为我不希望文件格式的默认编辑器配置与 ESLint 和 Prettier 发生冲突。

  • eslint.autoFixOnSave——我在这里将它设置为 true,因为我希望每次在保存文件时安装的插件都能正常工作。由于 ESLint 的配置关联了 Prettier 的配置,所以每次在点击保存时,它都会格式化和 lint 你的代码。


需要注意的是,当你运行 yarn lint:write 时,它也会 lint 和美化你的代码。


试想一下,如果你有 2 万行代码,然后通过手动的方式进行审计和改进,然后再想象一下用一个命令就可以完成所有事情。手动方法可能需要 30 天,而自动方法可能只需要 30 秒。


脚本已经设置好了,每次点击保存时,编辑器都会对特定文件做出神奇的回应。但是,并不是团队中的每个人都会选择使用 VS Code。不过没关系,我们可以更自动化一些。

husky

什么是 husky?


husky(https://github.com/typicode/husky)是一个 Git 钩子,你可以在提交代码前或在将代码推送到分支时执行某些特定的操作。


你所要做的就是安装 husky:


yarn add --dev husky
复制代码


然后在 package.json 文件中添加以下内容:


"husky": {       "hooks": {           "pre-commit": "YOUR_COMMAND_HERE",      "pre-push": "YOUR_COMMAND_HERE"      }  },
复制代码


每次在提交或推送代码时,它都会执行某个脚本或命令——比如运行测试用例或格式化代码。

lint-staged

什么是 lint-staged?


lint-staged(https://github.com/okonet/lint-staged)可以在暂存(Git staged)文件上运行 linter,这样就不会将错误的代码推送到分支上。


为什么要用 lint-staged?


在提交代码之前进行 lint 是很有意义的,你可以确保没有错误进入到代码库中,并且可以强制应用代码样式。但在整个项目上运行 lint 过程会很慢,而且有些 lint 结果可能无关紧要。你可能只想对要提交的文件进行 lint。


这个项目提供了一个脚本,这个脚本将执行任意的 shell 任务,并将暂存文件列表作为参数,按指定的通配模式进行文件过滤。


你要做的是安装 lint-staged:


yarn add --dev lint-staged
复制代码


然后在 package.json 文件中添加:


"lint-staged": {       "*.(js|jsx)": ["npm run lint:write", "git add"]  },
复制代码


这段配置的意思是先运行 lint:write 命令,然后将文件添加到暂存区域。它仅针对.js 和.jsx 文件运行这个命令,但你也可以根据需要针对其他文件运行这个命令。

husky 与 lint-staged 一起使用

每次提交代码之前,都会运行一个叫作 lint-staged 的脚本,这个脚本将运行 npm run lint:write 命令,这个将 lint 并格式化你的代码,然后将代码添加到暂存区并提交。


最终的 package.json 文件应如下所示。


{  "name": "react-boiler-plate",  "version": "1.0.0",  "description": "A react boiler plate",  "main": "src/index.js",  "author": "Adeel Imran",  "license": "MIT",  "scripts": {    "lint": "eslint --debug src/",    "lint:write": "eslint --debug src/ --fix",    "prettier": "prettier --write src/**/*.js"  },  "husky": {    "hooks": {      "pre-commit": "lint-staged"    }  },  "lint-staged": {    "*.(js|jsx)": ["npm run lint:write", "git add"]  },  "devDependencies": {    "babel-eslint": "^8.2.3",    "eslint": "^4.19.1",    "eslint-config-airbnb": "^17.0.0",    "eslint-config-jest-enzyme": "^6.0.2",    "eslint-plugin-babel": "^5.1.0",    "eslint-plugin-import": "^2.12.0",    "eslint-plugin-jest": "^21.18.0",    "eslint-plugin-jsx-a11y": "^6.0.3",    "eslint-plugin-prettier": "^2.6.0",    "eslint-plugin-react": "^7.9.1",    "husky": "^1.1.2",    "lint-staged": "^7.3.0",    "prettier": "^1.14.3"  }}
复制代码


现在,每当你提交代码时:


$ git add .$ git commit -m "some descriptive message here"
复制代码


它将根据.eslintrc.js 文件的所有规则对代码进行 lint 和格式化。有了这个,你就可以确保没有坏代码被推到生产环境中。

现在介绍一下 EditorConfig

首先在 app/根文件夹中创建一个.editorconfig 文件,然后在该文件中粘贴以下代码:


# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig fileroot = true
[*.md]trim_trailing_whitespace = false
[*.js]trim_trailing_whitespace = true
# Unix-style newlines with a newline ending every file[*]indent_style = spaceindent_size = 2end_of_line = lfcharset = utf-8insert_final_newline = truemax_line_length = 100
复制代码


那么 EditorConfig 是什么东西?


并不是每个人都会使用 VS Code,所以为了让每个人保持统一(例如在制表符空格或换行方面),我们使用.editorconfig,这样有助于强制执行某些规则。


支持 EditorConfig(https://editorconfig.org/)的编辑器包括 Web Storm、App Code、Atom、Eclipse、Emacs、bbedit,等等。


上述的配置将执行以下操作:


  • 去掉.md 和.js 文件中的尾部空格;

  • 将缩进样式设置为空格而不是制表符;

  • 缩进大小为 2;

  • 行尾是 lf,这样每个人不管使用的是哪种操作系统,都会有相同的行尾;

  • 文件末尾应该有一个新行;

  • 单行的最大度应为 100 个字符。


英文原文:https://medium.freecodecamp.org/these-tools-will-help-you-write-clean-code-da4b5401f68e


更多内容,可关注前端之巅(ID:frontshow)



2018-12-24 14:138678
用户头像

发布了 731 篇内容, 共 433.8 次阅读, 收获喜欢 1997 次。

关注

评论 2 条评论

发布
用户头像
vscode都写了,为何不加个webstorm的配置
2018-12-24 19:35
回复
没有更多了
发现更多内容

一文详解特权访问管理(PAM)

SEAL安全

安全 访问权限 访问管理 特权访问

开源 | WLock:高可用分布式锁设计实践

开源 分布式 分布式锁

增强分析在百度统计的实践

百度Geek说

数据库

一文搞懂│mysql 中的备份恢复、分区分表、主从复制、读写分离

MySQL 高并发 经验分享 签约计划第三季 8月月更

DBPack 数据库限流熔断功能发布说明

峨嵋闲散人

分布式事务 云原生 分库分表 dbmesh Database Mesh

属实不赖!Alibaba开源GitHub星标114K微服务架构全彩进阶手册

冉然学Java

Java 阿里巴巴 开源 微服务 微服务架构

以合规交易释放数据“红利”,合合信息旗下启信宝签约福建大数据交易所首批数商

合合技术团队

数据 峰会

连流量染色都没有,你说要搞微服务?

得物技术

架构 微服务 云原生

推荐一款微软出品的开发神器,体验不输IDEA!(含参考资料和项目源码)

收到请回复

面试 springboot 应届生 金九银十 java项目实战分享

Kotlin协程解析系列(上):协程调度与挂起

vivo互联网技术

kotlin 协程

为什么不做APP而要做小程序

源字节1号

小程序开发

基于RocksDB实现高可靠、低时延的MQTT数据持久化

EMQ映云科技

物联网 mqtt RocksDB emqx 8月月更

前端监控系列2 |聊聊 JS 错误监控那些事儿

字节跳动终端技术

APM 前端监控 火山引擎 JS错误

微服务性能分析|Pyroscope 在 Rainbond 上的实践分享

北京好雨科技有限公司

Kubernetes 微服务 云原生

人手一套的K8S命令集合,它来了!

wljslmz

云计算 Kubernetes 容器 8月月更

阿里大佬 推荐的 “ Spring Cloud Alibaba项目文档 ” 正式发布

冉然学Java

Java 微服务 Spring Cloud Alibaba

干货!这份阿里P8大佬纯手打总结Kafka学习笔记,真是yyds

了不起的程序猿

Java kafka java程序员 消息中间件 Java 开发

为什么电商云产品需要 Assisted Service Module (ASM) 模块的支持

Jerry Wang

typescript 电商 SAP 8月月更 Storefront

Groovy语境下的Map

FunTester

寻找OpenHarmony「锦鲤」|万元豪礼+技术干货全是你的!

OpenHarmony开发者

OpenHarmony

35岁程序员危机,有何破解之法?

博文视点Broadview

《数字经济全景白皮书》银行业数字普惠金融发展与优化策略分析 发布

易观分析

金融 数字经济全景白皮书 易观分析

StarRocks 技术内幕 | 基于全局字典的极速字符串查询

StarRocks

数据库

多原则等于无原则,微服务识别方法究竟该怎么选?

老坛架构

架构 微服务

DAPP和APP有哪些区别?多链跨链NFT铸造挖矿dapp系统开发技术原理分析

开发微hkkf5566

测试开发【Mock 平台】09 开发:项目管理(五)搜索、删除和Table优化

MegaQi

测试平台开发教程 8月月更

最常见的 10种网络安全攻击类型

郑州埃文科技

网络安全 IP地址 网络攻击

SpringBoot 日志的各种使用姿势,你真的用对了吗?

程序知音

Java spring 程序员 springboot 后端技术

用Rust编写的Linux内核GPU驱动程序,或将到来

非凸科技

Linux gpu rust 编程语言

一对一直播系统源码——多人语音聊天室

开源直播系统源码

直播系统源码 语音直播系统 一对一直播视频源码 一对一语音直播

Java 泛型 T,E,K,V,,傻傻分不清?

TimeFriends

8月月更

力荐!这些工具可以帮你写出干净的代码_语言 & 开发_Adeel Imran_InfoQ精选文章