玩工程化之萌新总结

大家好,这里是梅利奥猪猪!很久没更新了,新的一年的第一篇水文,想整点轻松快乐的活,想来想去,咸鱼的我貌似近期也没怎么学习,就在疯狂内卷加班,精神内耗(哭哭唧唧)!但在之前忙里偷闲的时候,刚好用cra(create-react-app)整活,玩了些工程化的东西(commitlint+prettier+cspell),今天就给大家带来中小型cv攻略之萌新如何简单玩耍工程化!

cra - 这篇水文的基石工具人

这里是我们这篇文章的起点-先来创建个ts项目吧!

贴心的cra工具人,已经在Getting Started告诉我们如何Selecting a template,其中就有如何Creating a TypeScript app

npx create-react-app my-app --template typescript
复制代码

创建好项目后,我们的第一步就大功告成了!

commitlint - 校验你的commit msg

正如标题所说的,commitlint做的就是校验我们的提交信息,可以让我们整个开发团队根据规范,让提交的信息更加清晰明了,也可以自定义些规则,如果没有按照规范来提交,就会报错提交失败!这里我们用官方推荐的规则commitlint/config-conventional,再贴个链接,讲解规则的配置项,以及例子

这里先简单讲解下commitlint的一个例子type-enum,让jym直观的感受,为什么用了这个能让我们提交信息规范化

[
  'build', // build
  'chore', // 辅助工具
  'ci', // ci
  'docs', // 文档
  'feat', // 新功能
  'fix', // 修复
  'perf', // 性能优化
  'refactor', // 重构代码
  'revert', // 回退版本
  'style', // 样式
  'test' // 测试
];
echo "foo: some message" # fails 默认定义的type-enum中没有foo,且foo没有任何意义(需要见名知意)
echo "fix: some message" # passes fix就是修复,冒号后面的内容就是描述修复了什么
复制代码

如果我们的提交信息中,都已type-enum中定义的作为开头,那我们之后查询git提交的历史,看起来就非常爽,也知道了自己具体做了什么,同事做了什么(新功能?修bug?重构?等等),当然除了type-enum,commitlint还有对提交信息的长度啊,大小写,是否描述为空等做了校验!我们赶紧来体验下吧!cv搭环境吧

这里我们先直接敲git log --oneline,贴心的cra工具,帮我们搭好了git环境,并提交了一条信息Initialize project using Create React App,但很明显,他并不是commitlint要求的格式

找到我们commitlint官方的Getting started,大家可以看官网,也可以看我贴出来的(可以直接cv用),也增加了少许注释讲解

# Install commitlint cli and conventional config 这里是mac哦
npm install --save-dev @commitlint/{config-conventional,cli}
# For Windows: 这里是windows哦
npm install --save-dev @commitlint/config-conventional @commitlint/cli

# Configure commitlint to use conventional config
# mac玩家直接复制该命令跑就可以了
# windows玩家注意下,这里有个坑
# 直接用该行命令搭环境,可能会导致后续git commit提交报错
# 因为生成文件的编码格式可能有问题,所以我windows搭直接手动新建文件加手动挡贴代码
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js

# Install Husky v6
npm install husky --save-dev
# or 注意是或者,只要跑其中一个就可以了
yarn add husky --dev

# Activate hooks
npx husky install
# or 注意是或者,只要跑其中一个就可以了
yarn husky install

# Add hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
# Sometimes above command doesn't work in some command interpreters
# You can try other commands below to write npx --no -- commitlint --edit $1
# in the commit-msg file.
# 注意是sometimes有问题,可以选择执行下面的命令
npx husky add .husky/commit-msg \"npx --no -- commitlint --edit '$1'\"
# or 注意是或者,只要跑其中一个就可以了
npx husky add .husky/commit-msg "npx --no -- commitlint --edit $1"

# or 注意是或者,只要跑其中一个就可以了
yarn husky add .husky/commit-msg 'yarn commitlint --edit $1'
复制代码

搭完以后,我们就可以先来个错误示范

git add .
git commit -m 'add commitlint'
复制代码

commit-error.png

漂亮,搭成功了,commitlint校验告诉我们明显不合规啊,那我们来个正确的,因为这属于辅助工具,所以我们应该type用chore

git commit -m 'chore: add commitlint'
复制代码

commit-success.png

提交成功了噢耶,这里再讲解下配置文件,请看配置规则的代码,结合commitlint-rules看更香

module.exports = {
	parserPreset: 'conventional-changelog-conventionalcommits',
	rules: {
		'body-leading-blank': [1, 'always'],
		'body-max-line-length': [2, 'always', 100],
		'footer-leading-blank': [1, 'always'],
		'footer-max-line-length': [2, 'always', 100],
		'header-max-length': [2, 'always', 100],
		'subject-case': [
			2,
			'never',
			['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
		],
		'subject-empty': [2, 'never'],
		'subject-full-stop': [2, 'never', '.'],
		'type-case': [2, 'always', 'lower-case'],
		'type-empty': [2, 'never'],
		'type-enum': [
			2,
			'always',
			[
				'build',
				'chore',
				'ci',
				'docs',
				'feat',
				'fix',
				'perf',
				'refactor',
				'revert',
				'style',
				'test',
			],
		],
	},
	...
};
复制代码

简单来说,怎么看懂这个配置,rules已经讲解了

  • Level [0..2]: 0 disables the rule. For 1 it will be considered a warning for 2 an error.
    • 0 - 表示禁用
    • 1 - 表示给警告
    • 2 - 表示错误
  • Applicable always|never: never inverts the rule.(Applicable 是指是否反过来执行。比如你 Level 是 2 时,正常的是就 “必须首字母大写”,反过来就是 “必须首字母不大写”)
    • always 正常
    • never 反过来
  • Value: value to use for this rule.
    • 设置规则的value

我宣布commitlint通关!

eslint - 管理代码质量的专家

在讲prettier之前,其实还是要简单提下eslint,因为他们有相爱相杀的关系。在说明他们之间的关系前,我先要表示cra工具人已经帮我们搭好了eslint。什么情况,竟然已经搭好了,那eslint是什么,帮我们做了什么呢?我们先启动下我们的react项目

yarn start
复制代码

启动后我啥也没看到啊,怎么看eslint做了什么。很简单,我们在App.tsx中随意写个变量

// src/App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  const test = 'test' // 这里是新加的代码
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
复制代码

来了来了,eslint出现了

show-eslint.png

过分了,你申明了这个test变量,但却不用它,给你警告!

其实eslint就如我们的大标题所说,他主要负责的职责就是管理代码质量,除了上述演示的no-unused-vars还有其他代码质量相关的检查,但eslint又不仅仅检查了代码质量,他还处理了代码风格一些问题,但又没有完完全全解决,所以我们的prettier就登场了。这里再贴一篇知乎大佬写的搞懂 ESLint 和 Prettier,大家有兴趣可以去看看哈

prettier - 管理代码风格的专家

为了让团队提交的代码风格一致,更加的美观赏心悦目,用prettier制定风格规范是有必要的,Let's cv。这里老样子,XDM可以根据官网一步一步cv,也可以看我讲解cv

# 安装prettier
yarn add --dev --exact prettier 
# 生成配置文件
echo {}> .prettierrc.json
# 创建.prettierignore,这个就类似.gitignore,你有不想提交的文件同样也会有不想格式化的文件
# 这行代码可以跑着玩下,也可以不跑,因为这个属于手动挡格式化,但我们肯定要工程化的
npx prettier --write .
复制代码

到这里我们已经简单装好了prettier,但还不够自动化,所以接下来我们要先让eslint和prettier搞基,在配置git hook让他在我们提交前做格式化代码的工作

ESLint (and other linters)

官方的原话已经描述的很清晰了If you use ESLint, install eslint-config-prettier to make ESLint and Prettier play nice with each other.,为了让他们玩的更开心,我们安装下eslint-config-prettier

npm install --save-dev eslint-config-prettier
复制代码

前面我们也说过了,eslint做了部分代码风格的事情,eslint-config-prettier就是为了让prettier覆盖eslint,让prettier完全替他做代码风格的事情,你看有这么一句描述Then, add "prettier" to the "extends" array in your .eslintrc.* file. Make sure to put it last, so it gets the chance to override other configs.,注意需要放到extends最后,也给出了例子

{
  "extends": [
    "some-other-config-you-use",
    "prettier"
  ]
}
复制代码

那我们的cra貌似没有看到配置文件.eslintrc.* file,但我们可以在package.json这可以配置

"eslintConfig": {
  "extends": [
    "react-app",
    "react-app/jest",
    "prettier"
  ]
},
复制代码

这样,好基友俩就能play nice with each other了

Git hooks

这里继续跟着文档复制

# 我们装过husky了,所以这里直接装lint-staged
yarn add --dev husky lint-staged
# 这个之前在commitlint也跑过了,忽略
npx husky install
# 在scirpt中加条命令,也可以忽略
npm set-script prepare "husky install"
# 这行是要执行的,添加pre-commit的hooks,即提交前执行lint-staged
npx husky add .husky/pre-commit "npx lint-staged"
复制代码

然后就是在package.json里配置lint-staged,执行我们的prettier命令,lint-staged是因为跑了husky的pre-commit而执行

{
  "lint-staged": {
    "**/*": "prettier --write --ignore-unknown"
  }
}
复制代码

这样我们的prettier就装好了,如何玩耍呢,我们随意改改App.tsx的代码风格,然后commit下看下效果就可以啦!

prettier.gif

哈哈完美,离prettier通关还差一丢丢了,那就是配置美化代码的规则了,请看OptionsConfiguration File

比如可以配置字符串用单引号还是双引号,结尾需不需要分号等等,这里我就不多举例了,XDM自己玩吧,玩好以后即通关prettier(滑稽脸)

cspell - 让我来check你的spell

不知道大家有没有遇到过,项目中一些方法命名变量命名,拼写错误的!这是不是非常难受!比这个更难受的可能是以下的这样的自言自语

“草,怎么有人单词都拼错了太不专业了,看看哪个xxx写的”

查看提交记录+蓄力中

“原来是我这个xxx写的(哭笑不得)”

这个时候cspell就可以发挥他的作用了,意思就是check spell,拼错的单词就别想提交成功了!

我们依然去官方文档,在根据我们的理解cv搭工程化哈

# 安装依赖
yarn add -D cspell 
# 执行该命令指的是检查所有文件
cspell "**"

Examples:
  cspell "*.js"                   Check all .js files in the current directory
  cspell "**/*.js"                Check all .js files from the current directory
  cspell "src/**/*.js"            Only check .js under src
  cspell "**/*.txt" "**/*.js"     Check both .js and .txt files.
  cspell "**/*.{txt,js,md}"       Check .txt, .js, and .md files.
  cat LICENSE | cspell stdin      Check stdin
复制代码

因为我们需要工程化,自动校验拼写问题,我们可以在.husky文件下的pre-commit生命周期添加cspell指令

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx cspell "**"
npx lint-staged
复制代码

是不是很熟悉,之前的prettier就是在commit前跑lint-staged,来完成自动格式化代码,现在又追加了检验单词拼写

我们在App.tsx故意写错个单词,然后提交看下吧,代码如下

import React from "react";
import logo from "./logo.svg";
import "./App.css";

function App() {
  const apple = 'aplpe' // 赋值的字符串明显拼写错误吧
  console.log(apple)
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
复制代码

cspell-wrong.png

看来搭cspell很成功,而且发现了不止我们的aplpe报错了,还报错了其他的东西,什么commitlint等等

很合理,这的确不是一个正确的英文单词,但在我们技术领域,有很多这样的,比如vue,antd这些,虽然非技术人员的老外肯定不认识,但作为前端打工仔,这些我们认的呀,那怎么办,怎么处理,别急,cspell当然帮我们想到了这个,我们来看下Configuration,我们项目根目录下新建个cspell.config.js,根据对文档的理解,作出如下处理

module.exports = {
  // Version of the setting file.  Always 0.2
  version: "0.2",
  // language - current active spelling language
  language: "en",
  // words - list of words to be always considered correct
  // 配置项目中可以出现的,我们技术人员认可的'单词'
  words: ["commitlint", "antd"],
  // flagWords - list of words to be always considered incorrect
  // This is useful for offensive words and common spelling errors.
  // For example "hte" should be "the"
  // 即使拼写正确,但也不希望出现在我们项目中的,比如一些辱骂的词汇之类的
  flagWords: ["fuck"],
  // 哪些路径下的文件不用检查拼写
  ignorePaths: [
    "node_modules/**",
    "src/reportWebVitals.ts",
    "package.json",
    "cspell.config.js",
    "public/**",
  ],
};

复制代码

改好后一提交,果然没问题了,直接提交成功

cspell相关补充

在之前的配置下,我们的cspell已经搭好了,但有这么个问题,如果我们的commit-msg里的信息,单词有拼错怎么办!的确是有这种可能的,所以我们应该在git hook中的commit msg周期里添加命令,校验我们的msg信息

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit $1
cat $1 | npx cspell --no-progress --no-summary stdin

复制代码

可以这么理解:commit-msg字符串赋值给了变量,在用cspell对这个变量校验,话不多说我们直接这么测试下

git add .
git commit -m 'test: aplpe'
复制代码

cspell-error.png

大功告成,说明commit-msg的hook触发,并且检验了我们提交的信息!

到这步,恭喜XDM就通关这篇水文的所有关卡了!希望能帮助到大家,虽然cv简单,但还是要简单练习下的,萌新猪猪和大家一起进步成长!

参考

おすすめ

転載: juejin.im/post/7049695230550868005