基本 JavaScript 工具
快速摘要
软件开发很棒也很有趣,但如果不重视和优先考虑开发者体验,开发过程可能会变得混乱,并产生非常不良的影响。一些标准的开发实践以及合适的工具可以极大地改善这种体验。这也有助于保持代码库的整洁和代码库的健康。在本文中,我们将介绍一些开发实践和必备工具,以帮助您提升开发体验。
观众
本文主要面向 JS 开发者,涵盖 JS 生态系统相关的工具。然而,同样的概念也可以在其他语言中运用,并借助其他语言提供的工具来实现。我们将在本文中讨论以下主题。
- 使用ESLint进行代码 Linting 。
- 使用Prettier进行代码格式化。
- 设置Git Hooks进行 linting 和代码格式化。
- 使用Commitizen进行常规提交。
- 适用于 CI/CD 的Github Actions
代码 Linting
代码 linting 至关重要,尤其是在使用 JavaScript 这样的解释型语言时。linters 本质上是静态代码分析器,它会在不运行代码的情况下扫描代码,并标记任何程序错误、代码风格错误以及任何可疑的约定。在代码库中正确设置 linter 可以帮助尽早发现错误,并确保遵循一些标准实践。这可以使代码库保持整洁,并有助于代码审查。
Linters 可以强制执行代码样式和规则,例如没有未使用的变量或没有 console.log 语句或没有未使用的导入,事实上它是一个非常强大的工具,可以做更多的事情。
设置 Linter 可能繁琐且费力,但一旦你采用它并在团队中正确使用,它会带来很好的效果。我个人认为 Linter 和类似的工具应该随语言本身提供,开发人员不必费心设置。Deno(JavaScript 和 TypeScript 的安全运行时)内置了 JavaScript 和 TypeScript 的 Linter 和格式化程序,大大提升了这种体验。
现在我们已经对 Linter 有了基本的了解,接下来看看如何在 TypeScript 项目中设置它。我们将使用 ESLint,它在 JS 生态系统中非常流行,并且完全可插拔。ESLint 中的每条规则都是一个插件,这意味着您可以从基本配置开始,然后通过添加更多规则作为插件来扩展规则以满足您的需求。
创建一个新文件夹并运行npm init -y
以初始化您的项目,这将package.json
在根目录中创建一些存根字段。
接下来,将所需的内容安装dev-dependencies
到项目中。
yarn add -D nodemon ts-node eslint typescript @typescript-eslint/eslint-plugin @typescript-eslint/parser
让我们首先通过运行来快速设置 TypeScript,tsc --init
这将初始化tsconfig.json
项目根目录中的文件,我们唯一要更改的是取消注释outdir
选项并将其更改为dist
"outDir": "dist"
接下来,在项目的根目录中添加一个.eslintrc
文件。这将是eslint
我们可以自定义规则的配置文件。为了快速开始,让我们在文件中添加一个最低限度的配置。
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
]
}
让我们简单看一下这些选项,root
键基本上告诉 eslint 停止在父目录中查找配置文件。默认情况下,eslint 会在所有父文件夹中查找配置文件,直到根目录,这可能会导致意外的结果。此外,当您有一个 monorepo 并且每个项目使用不同的配置时,此选项会非常方便。
键值extends
用于添加项目所需的配置。它可以是指定配置的字符串,也可以是配置文件的路径。这里我们使用了两个配置:第一个是eslint-recommended,第二个是 typescript-eslint recommended 。你也可以使用airbnb-typescript配置,它也非常流行。
现在让我们添加一些脚本,以便package.json
在开发模式下运行我们的项目,并添加一个用于 linting 的脚本。
"dev": "nodemon --watch '**/*.ts' --exec 'ts-node' src/index.ts",
"lint": "eslint . --ext .ts"
为了测试我们的 eslint 设置,让我们创建一个index.ts
文件和一个非常简单的 for 循环,其中包含一个未使用的变量。
//src/index.ts
const range = 10;
for (let i = 0; i < 10; i++) {
console.log("i : ", i);
}
现在让我们运行yarn lint
,我们将在控制台上收到警告。
这很好,我们的 eslint 设置正在运行,但是假设我们想要对我们的代码库更加严格,并希望这是一个错误并导致 lint 失败,那么请转到您的.eslintrc
文件并添加以下规则。
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"rules": {
"no-unused-vars": "error" // "error" | "warn" | "off"
}
}
现在,如果您运行,yarn lint
您的控制台将显示此错误,并且 lint 将不会成功,此外,如果您在 vs code 上安装了 eslint 扩展,它将突出显示此问题。
我们还可以添加另一个脚本来自动修复 lint 问题,请注意,并非所有问题都可以自动修复,您可以在此处获取可以自动修复的所有规则的列表。
"lint-fix": "eslint . --ext .ts --fix"
这基本上就是关于 linting 的设置,我希望你现在可以为自己创建一个心理模型,并看看如果使用得当,这个工具会有多么有用。
代码格式化
不得不承认,代码库中代码风格各异会造成混乱,如果不加以控制,你会看到代码库中各种代码约定都被遵循。这时,代码格式化程序就派上用场了。但在我们开始在项目中设置代码格式化程序之前,我们首先需要明白,代码格式化程序和代码检查工具本质上并非一回事,虽然它们之间只有一线之隔,但它们的用途却截然不同。代码格式化程序本质上处理代码的格式化,并应用你指定的代码样式,它们不会检查代码中是否存在潜在的错误或问题,而是严格遵循代码样式。
Prettier 是 JS 生态系统中非常著名的工具,我们将在我们的项目中设置它,使用 Prettier 我们可以强制执行样式规则,例如最大长度、制表符宽度、单引号、分号等。它基本上是一个固执己见的代码格式化程序,它会获取您的代码并将其解析为 AST(抽象语法树),丢弃原始样式,之后它会使用您指定的代码样式漂亮地打印 AST。
让我们开始吧,首先我们需要安装开发依赖项
yarn add -D prettier eslint-config-prettier eslint-plugin-prettier
让我们快速解释一下上述开发依赖项以及它们的用途。
prettier
:固执己见的代码格式化程序。eslint-config-prettier
:用于禁用所有可能与 prettier 冲突的 eslint 规则。eslint-plugin-prettier
: 作为 eslint 规则运行 prettier
.prettierrc
现在在目录的根目录中创建一个文件并添加以下配置。
//.prettierrc
{
"semi": true,
"trailingComma": "none",
"singleQuote": false,
"printWidth": 120,
"tabWidth": 2,
"arrowParens": "always",
"bracketSpacing": true
}
这些规则指定在末尾放置分号、删除尾随逗号、对字符串使用双引号等,您可以在此处阅读有关规则的更多信息并根据您的喜好进行设置。
现在我们已经设置了规则,让我们添加一个脚本来格式化我们的代码。
"format": "prettier --config .prettierrc 'src/**/*.ts' --write"
就这样,我们在项目中配置了 Prettier,现在每当你运行这个脚本时,它都会src
根据你定义的配置格式化目录中的所有源代码。测试一下,使用一些单引号或删除分号,然后运行yarn format
。你也可以安装 Prettier vs code 扩展,并将其设置为“保存时格式化”。
现在我们已经设置好了 Prettier,让我们用 eslint 来配置它,.eslintrc
按如下所示更新,这样你就可以使用 Prettier 与 eslint 一起工作,并在 eslint 配置中将其配置为插件。
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "prettier"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"no-unused-vars": "error",
"prettier/prettier": "error"
}
}
Git 钩子
太棒了!如果你一直关注到这里,接下来就是最激动人心的时刻了。你一定会想,虽然我们设置了这些工具,但有人仍然可以在不运行这些脚本的情况下提交到仓库,这时 git hooks 就派上用场了。Git hooks 只是一些脚本,每次在仓库中发生事件时都会自动运行。我们将使用一个名为husky的工具,它能让 git-hooks 的使用更加轻松。
让我们快速将其安装为开发依赖项。
yarn add -D husky
// Also add a prepare script to your package.json as below.
"prepare": "husky install"
// Now run
yarn prepare
prepare
是一个将在 npm 上运行的生命周期脚本npm install
,它将确保每次安装 Node 模块时,Husky 也会同时安装。点击此处了解更多关于生命周期脚本的信息。
就这样,Husky 现在已经在我们的项目中设置好了,我们可以配置它,让它在提交之前运行我们的lint
和format
脚本,为此,我们可以使用pre-commit
提交前运行的钩子。现在让我们添加这个钩子,打开终端,运行以下命令。
npx husky add .husky/pre-commit "yarn lint && yarn format"
你会注意到,现在.husky
你的仓库根目录下多了一个文件夹,里面有一个pre-commit
包含以下内容的文件。每次你提交到仓库时,这个钩子都会运行。
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint && yarn format
现在尝试在代码库中提交一些内容,你会发现代码lint
和format
脚本会先执行。如果一切正常,你的提交就会成功添加。如果出现问题,提交将无法提交到代码库,你必须修复这些问题才能提交。现在你应该能够对此有一个大致的了解,这可以确保不会将任何可能存在错误或样式问题的代码提交到代码库。如果正确遵循这些约定,可以帮助你节省大量的代码审查时间。
这种配置很棒,但如果你注意到这种方法有一个问题,那就是如果我们的代码库非常庞大,并且每次提交都要运行 linting 和格式化,那么这可能会耗费更长的时间,而这并非我们的预期用例。我们只想对已暂存的文件运行它,因为理想情况下,只有那些提交到仓库的文件才需要检查。这时,另一个工具lint-staged
就派上用场了,它可以确保我们的预提交钩子只在暂存的文件上运行。而且,这也可以非常快速地配置。
yarn add -D lint-staged
// Add below config to your package.json
"lint-staged": {
"src/**/*.ts": [
"yarn lint",
"yarn format"
],
},
并将你的pre-commit
钩子更新为运行npx lint-staged
而不是运行yarn lint && yarn format
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
就是这样,现在 lint 将仅针对暂存的文件运行。您可以通过在仓库中创建一个包含一些 lint 问题的文件来快速测试它,但不要暂存它,同时暂存一些符合 lint 规则的其他文件。您应该注意到 git commit 可以正常运行,但是如果您暂存包含 lint 问题的文件,它将阻止提交并在终端上显示应修复的 lint 错误。如果您想对整个项目进行 lint 测试,仍然可以通过运行 来完成yarn lint
。现在,我们的工具已经设置得足够好,以确保整个团队可以遵循它并遵守相同的编码标准和样式指南。
常规提交
我们的开发设置基本完成,但团队仍然可以在一个方面采用不同的约定,那就是提交信息。没错,每个人在添加提交信息时都有不同的偏好,我们需要确保团队遵循标准约定。我们将在项目中采用约定式提交规范,并使用一个名为commitizen
本规范的一般语法如下
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
// Example
feat(landing-page): add new landing page
A new landing page for the website...
Closes #<github-issue-number>
好了,现在我们已经了解了规范,让我们配置我们的项目来使用这个工具。
yarn add -D commitizen cz-conventional-changelog
并将其添加到您的pacakge.json
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
"scripts": {
"cz": "cz",
...
}
注意:如果您最终命名了您的脚本,commit
那么由于repo 中提到的这个问题,它可能会运行两次。
现在尝试通过运行提交到仓库yarn cz
,终端上会提示你几个问题,以便你进行正确的提交。太好了,现在我们的常规提交已经设置好了,我们还可以通过运行以下命令将其设置为 git hook,并使用我们的prepare-commit-msg
钩子运行 commitizen,该钩子由 调用。git commit
但是,这种方法存在一个问题,运行时会触发两次 git commit yarn cz
。这个问题在仓库中已公开,我建议在问题解决之前不要使用此方法,并依赖之前的脚本。yarn cz
npx husky add .husky/prepare-commit-msg "exec < /dev/tty && node_modules/.bin/cz --hook || true"
Github Actions
在最后一部分,我们将重点介绍如何设置 GitHub Action,以确保我们的 lint 和 format 作业在每次提交时都运行,以及 GitHub Action 如何帮助我们构建 CI/CD 流水线。在现代软件开发中,设置良好且快速的 CI/CD 流水线至关重要。随着软件的发展,手动编译构建版本可能会变得非常繁琐,如果需要在多个平台上进行编译,您可以想象这会耗费多少时间。
Github Actions 是一款便捷的工具,可以自动化软件工作流程,并直接从你的 Github 代码库提供 CI/CD。Github Actions 是事件驱动的,基本上需要一个.yaml
文件,你可以在其中分步提供配置。
使用 Github Actions 时需要考虑的一些关键术语包括
- 工作流:包含一个或多个作业的自动化工作程序。
- 事件:触发工作流程的活动(例如推送到分支)
- 作业:在同一个运行器上执行的一组步骤。
- 步骤:可以对作业执行命令的任务。
您可以在官方文档中阅读有关这些内容的更多信息。
首先,如果您还没有在项目中初始化一个 git 仓库,请运行git init
并提交您的更改到仓库。请确保您添加了一个.gitignore
文件,并在其中添加了node_modules
和dist
,这样它们就不会被提交到仓库。
接下来,在你的 Github 帐户上创建一个 repo,并复制远程的原始 URL,现在转到你的本地 repo 并运行
git remote add origin <remote-repo-origin>
git push -u origin <branch-name>
接下来,转到你的 Github 仓库,单击“Actions”选项卡,然后选择“Set up a workflow yourself”
在编辑器中命名文件lint.yml
并清除默认操作并将其替换为。
name: Lint
on: [push]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js environment
uses: actions/setup-node@v2.4.0
with:
node-version: '14.16.1'
- name: Install Node Modules
run: npm install
- name: Lint and format
run: |
npm run lint
npm run format
这个 action 文件非常简单,您应该能够轻松浏览。我们将工作流名称声明为 Lint,其中包含一个作业。一个工作流可以包含多个作业,默认情况下,作业并行运行,但可以使用文件中的语法lint
配置它们按顺序运行。needs <job-id>
.yml
接下来,我们指定在 Ubuntu 的最新版本上运行该作业,并使用市场操作设置 Node v14.16.1 。之后,我们只需安装 Node 模块并运行 lint/format 脚本。
请注意,这是一个非常简单的示例,但您可以根据自己的需求进行扩展。例如,假设您已在代码库中设置了测试,那么您可以定义另一个test
在测试完成后运行的作业linting
。如果测试作业成功,您可以运行另一个build
作业来编译构建并部署到暂存区。您基本上可以根据自己的需求进行配置,并自动化您的开发工作流程。Github Actions 确实是一个强大的工具,您绝对应该好好研究一下。
你可以在我的 GitHub 仓库中看到所有这些操作
结论
这篇博客的目的并非深入探讨每个工具,而是概述所有这些工具,它们能够帮助我们改进开发流程,并确保更佳的开发体验。设置这些工具可能是一项非常枯燥繁琐的任务,但它们是你的好朋友,一旦你在代码库中正确使用它们,你就不会后悔。欢迎在评论区分享你的想法,或在Twitter上与我联系。
鏂囩珷鏉ユ簮锛�https://dev.to/asjadanis/essential-javascript-tooling-139a