AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

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

  • 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:1311578
用户头像

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

关注

评论 2 条评论

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

加入DevRun软件开发流水线实战营,即刻开启你的职场竞争力之旅!

科技热闻

一文看懂:小程序游戏需要版号吗?

FN0

FuncGPT(慧函数)教你用Mybatis进行一对一查询映射处理

SoFlu软件机器人

一张图读懂TuGraph Analytics开源技术架构

TuGraphAnalytics

大数据 分布式 流计算 图计算 流图

2023年科技趋势展望报告,这几个领域程序员可以恰饭

互联网工科生

人工智能 软件开发 麦肯锡

走进大模型

统信软件

人工智能 深度学习 大模型

如何将数据从 InfluxDB 无缝接入到 TDengine 中?来看看

TDengine

tdengine Influxdb 时序数据库

k8s发布应用

tiandizhiguai

微服务 云原生 k8s

头脑风暴小工具-影响地图

Bruce Talk

敏捷开发 Agile Product Owner 影响地图

首批通过!柏睿数据旗下数据库产品获强制性国标最高级别认证

新消费日报

知识管理工具和方法有哪些?分享15种

爱吃小舅的鱼

产品经理 PingCode wiki软件 知识库管理软件

软件测试|人工智能如何帮助测试工程师解决问题?

霍格沃兹测试开发学社

云服务之PaaS:PaaS怎么帮助企业走向云

高端章鱼哥

云计算 低代码 PaaS JNPF

图智能在反洗钱方向的应用实践丨Fabarta 技术专栏

Fabarta

图计算 图分析 反洗钱 图智能 智能风控

国内智慧工业的实践,在一首曙光《长歌行》中

脑极体

AI 算力 数智化 曙光

cad设计绘图必备:AutoCAD 2024激活中文附补丁安装教程

mac大玩家j

Mac软件 CAD绘图 CAD设计 cad工具

常用的国内外组态软件推荐

2D3D前端可视化开发

物联网 组态软件 工业组态软件 web组态软件 SCADA

融云:AI 机器人在社交软件中的花样存在

融云 RongCloud

AI 融云 社交软件 AIGC My AI

Easysearch 跨集群复制实战

极限实验室

easysearch

软件测试|如何使用ChatGPT生成思维导图

霍格沃兹测试开发学社

Last Week in Milvus

Zilliz

非结构化数据 开源社区 Milvus Zilliz 向量数据库

什么是HTTP代理?HTTP代理的作用?HTTP代理怎么设置?

巨量HTTP

代理IP IP地址 http代理 socks5代理

ARTS 薪火重启之第二周

渣渣辉

社交语聊平台运营,需要哪些资质?语聊APP原生开发和混合uniapp开发的利弊分析

山东布谷科技胡月

语音聊天系统软件开发 语音直播平台开发 语音聊天室开发 语音程序源码 社交直播APP开发

九科信息成功签约中交房地产集团有限公司RPA项目

九科Ninetech

几款常用基于Web的组态编辑器

2D3D前端可视化开发

物联网 web组态 web组态软件 组态可视化 web组态编辑器

融云深度参与「新加坡 GTLC 大会」,连接亚太机遇、开拓国际市场

融云 RongCloud

通信 服务 融云 GTLC 东南亚

又一可视化低代码神器!云耀云服务器L实例正式发布

mecchi

软件开发 云主机 云服务器 博客搭建

唯一受邀参会通信服务商!融云出席数字经济头部盛会「中数大会」并发言

融云 RongCloud

人工智能 互联网 通信 数字 融云

我是如何使用Spring Retry减少1000 行代码

越长大越悲伤

Java spring retry spring-retry

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