【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

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

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

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

关注

评论 2 条评论

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

秒级响应,显著增效:明日控股携手奇点云,打造大宗贸易的数据中台标杆

Geek_2d6073

上一任留下的 Eureka,我该如何提升她的性能和稳定性(含数据比对)?

阿里巴巴云原生

阿里云 微服务 云原生

从 Greenplum 到 Databend,万全网络数据库平台架构演进

Databend

数据库迁移

物流快递电子面单对接规则指南

快递鸟

电子面单

点赞!HashData连续三年获评数据猿“最具投资价值企业奖”

酷克数据HashData

一文深度解读多模态大模型视频检索技术的实现与使用

阿里云视频云

云计算 大模型 视频云

低代码开发助力业务效能高速提升

快乐非自愿限量之名

低代码 企业转型 数字转型

大家都在用哪些团队项目管理工具协作?分享6类12款

PingCode

项目管理 项目管理软件

为什么跨境电商成为海外云手机的主要受众群体?

Ogcloud

云手机 海外云手机 跨境电商云手机 云手机海外版

亚洲杯+欧洲杯+奥运会观赛“体育直播平台”如何开发方法

软件开发-梦幻运营部

传统外贸和代购独立站的区别

tbapi

传统外贸 外贸独立站

DAPP合约代币质押流动性挖矿系统开发丨源码丨技术设计

l8l259l3365

据说这道Go面试题90%的人都搞错了!

王中阳Go

面试题 面经 defer Go 语言 断点

探索 Vue 3.0 下的低代码创新

不在线第一只蜗牛

低代码 开发 Vue3 API

一文详解全栈可观测的实现路径

阿里巴巴云原生

阿里云 云原生 可观测

低代码是软件开发的未来吗?

这我可不懂

软件开发 低代码开发 JNPF

Comparison between IPQ9574 and IPQ9554 | MLO EHT Solution Unveils the WiFi 7 CPU for Industrial

wallyslilly

AI for Good | AI+环保,点亮可持续的智能未来

澳鹏Appen

人工智能 AI向善 环境保护

区块链开发项目:构建去中心化未来的蓝图

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

最佳在线项目管理网站揭晓:2024年全方位对比15大热门工具

PingCode

项目管理 项目管理工具

选择海外云手机需要考虑什么?

Ogcloud

云手机 海外云手机 云手机海外版

小红书如何做混部?

阿里巴巴云原生

阿里云 云原生 Koordinator

手把手系列!无需 OpenAI 即可搭建 RAG 应用

Zilliz

Milvus openai AIGC LLM rag

17 位社区大咖寄语,Seata 进入 Apache 孵化器

阿里巴巴云原生

Apache 阿里云 云原生 seata

Higress 开源一周年:新版本,新标准,新工具,新征程

阿里巴巴云原生

阿里云 开源 云原生 Higress

软件测试学习笔记丨Linux数据处理

测试人

软件测试

【完整版教程】iOS混淆加固原理篇

上市难不上市更难,谁能佐证中国企服的光明前途?

ToB行业头条

2024年首期OpenHarmony繁星计划师资培训在东莞圆满举办

新消费日报

使用云手机运营TikTok,实现更多可能性

Ogcloud

云手机 海外云手机 tiktok云手机 云手机海外版

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