霞的云原生之旅: 前端工程化

前言本

本人现为一个学生身份, 美梦是作为基础建设的架构师, 本文意为编写一个通用的前端工程的模板, 没有经过一个长久的实践, 本文可能写的比较粗糙, 有错误和改进请友善提出

说明

使用Husky + Oxlint + ESLint + StyleLint + Prettier + Commitlint 作为基础设施库

  • Husky: Git hooks工具,通过配置一系列钩子,可以在git操作的不同阶段执行相应的命令, 这里使用它在代码提交到仓库前的检查, 使用使用Oxlint快速检索错误,然后执行ESLint检查代码规范与Prettier进行代码格式化输出, 统一代码规范
  • Oxlint: 现阶段只有Lint功能开发比较能用, 对于大型项目, 在CI时使用它会运行的比较快
  • ESLint: TS/TSX/Vue等代码的代码样式限制与格式化与修复
  • Prettier: TS/TSX/Vue/Markdown等文件的代码样式格式化
  • StyleLint: CSS/SCSS/Less等文件的排序,格式化
  • Commitlint: git commit时的规则校验

本文均使用pnpm包管理器, 但是部分包含npm的使用方法, 在这里它们的区别可能就在于指令的用法不同

Husky

作用

Git hooks工具,通过配置一系列钩子,可以在git操作的不同阶段执行相应的命令

官方文档

  1. 安装

如果.git目录不是在前端项目里,如:

bash 复制代码
. 
├── .git/ 
├── backend/ # No package.json 
└── frontend/ # Package.json with husky

则需要修改prepare的内容, 不使用pnpm exec husky init, 需要手动在package.json修改为:

json 复制代码
"prepare": "cd .. && husky frontend/.husky"

如果手动修改了scriptsprepare,需要重新执行一次

arduino 复制代码
pnpm prepare

注意, 如果.git目录不是在前端项目里, 那么pre-commit也要修改进入到对应的目录, 例如:

有这样的目录结构:

bash 复制代码
. 
├── .git/ 
├── backend/ # No package.json 
└── frontend/ # Package.json with husky

那么, 对应的pre-commit文件内容就应该这样写:

bash 复制代码
cd frontend

pnpm test

Oxlint

定义

检查文件是否按照定义的规则进行编写

在工程化的作用(扮演的角色)

它现阶段不能直接代替ESLint, 它没有修复代码的功能, 只是它使用了Rust编写的工具, 运行很快, 现阶段, 作者推荐在CI阶段时运行在ESLint之前,这样,大部分常见问题还没走到 Eslint 这一步就被 Oxlint拦截, 大大减少大型项目的CI流水线的运行时间

oxc-project.github.io/docs/guide/...

csharp 复制代码
pnpm add -D oxlint

Usages 用法

  • npx oxlint@latest --rules 以获取规则列表。
  • npx oxlint@latest --help 以获取配置说明

有用的选项和示例

  • --deny-warnings 将警告转换为错误,对于退出代码为 1 的 CI 失败很有用。
  • -D all 拒绝(打开)所有规则。
  • -A all -D eqeqeq 运行单个规则。
  • -D correctness -D perf -A debugger -A eqeqeq 拒绝(打开)和规则,并允许(关闭) correctness debuggereqeqeq perf 规则。
  • -c ./eslintrc.json使用该rules字段配置规则,如 ESLint 中所述。仅json` 支持格式

在package.json添加:

ini 复制代码
pnpm pkg set scripts.lint-check="oxlint"

如下效果:

json 复制代码
{
...
"scripts": {
	...
    "lint-check": "oxlint",
	...
  },
...
}

.husky/pre-commit添加

bash 复制代码
cat >> .husky/pre-commit <<EOF
pnpm lint-check
EOF

检查:

sql 复制代码
pnpm lint-check

lint-staged

作用

在提交代码前进行lint检查时,可以让lint只检查git暂存区(staged)的文件,而不会检查所有文件

shell 复制代码
pnpm add --save-dev lint-staged

package.json

json 复制代码
{
"lint-staged": {
    "src/**/*.{ts,tsx,js,jsx}": [
      "oxlint"
    ]
  },
}

ESLint

  1. 安装
shell 复制代码
pnpm create @eslint/config

or

kotlin 复制代码
npm init @eslint/config
  1. 添加配置
  • --cache:该参数启用了 ESLint 的缓存功能,以提高重复运行 ESLint 时的性能。ESLint 将会缓存 lint 结果和文件状态,从而避免不必要的重新检查。
  • --max-warnings 0:此参数规定了允许的最大警告数量。在这个例子中,设置为 0 表示如果有任何警告产生,将被视为错误而导致命令失败。
  • src:指定需要进行 ESLint 检查的目录或文件。在这里,它表示对 "src" 目录进行检查。
  • --ext ts,tsx:这个参数指定了 ESLint 将要检查的文件扩展名。在这里,它表示 ESLint 将检查扩展名为 ".ts" 和 ".tsx" 的文件。
  • --fix:该参数告诉 ESLint 尝试自动修复发现的问题。如果某些问题可以被自动修复,ESLint 将会尝试修改源代码以修复这些问题。
ini 复制代码
pnpm pkg set scripts.eslint="eslint src/**/**{.ts,.tsx}"

pnpm pkg set scripts.eslint:fix="eslint --cache --max-warnings 0 src --ext ts,tsx --fix"
  1. 添加忽略格式化的目录
bash 复制代码
echo node_modules > .eslintignore 
  1. 检查是否正常运行
matlab 复制代码
pnpm eslint
pnpm eslint:fix

Prettier

  1. 安装
  • --save-exact 标志用于确保安装的包版本是精确匹配的
bash 复制代码
pnpm install -D --save-exact prettier
  1. 创建配置文件 创建一个prettier配置文件,并写入基本的配置:
bash 复制代码
cat > .prettierrc.json << EOF
{
  "semi": true,
  "tabWidth": 2,
  "singleQuote": true,
  "printWidth": 80,
  "trailingComma": "all",
  "endOfLine": "lf"
}
EOF
  1. 创建prettier忽略文件(eslint 默认会忽略 node_modules):
bash 复制代码
echo node_modules > .prettierignore
  1. 解决prettier规则与ESLint规则的冲突
arduino 复制代码
pnpm add -D eslint-config-prettier

因为ESLint支持多种配置文件, 本文使用yml形式来保存配置, 编辑.eslintrc.yml: 在extends添加prettier

yml 复制代码
extends:
  - prettier

安装和配置eslint-plugin-prettier插件以便将Prettier作为ESLint规则运行,并将差异报告为单个ESLint问题:

json 复制代码
pnpm add -D eslint-plugin-prettier

.eslintrc.yml文件中添加配置:

yml 复制代码
rules: {
  prettier/prettier: error
}
  1. package.jsonlint-staged选择一个规则进行添加:
  • "**/*": "prettier --write --ignore-unknown": 让可识别的文件都使用prettier进行格式化
  • "*.{ts,tsx,js,jsx,cjs,mjs,vue,css,scss,less,md}": "prettier --write": 针对特定的文件类型进行格式化

示例:

arduino 复制代码
pnpm pkg set lint-staged."**/*"="prettier --write --ignore-unknown"

如下效果:

json 复制代码
{
	"lint-staged": {
	    "*.{ts,tsx,js,jsx,cjs,mjs,vue,css,scss,less,md}": "prettier --write --ignore-unknown",
	    "**/*": "prettier --write --ignore-unknown"
  },
}

Commitlint

  1. 安装
  • mac:
shell 复制代码
pnpm add -D @commitlint/{cli,config-conventional}
  • windows
shell 复制代码
npm install --save-dev @commitlint/config-conventional @commitlint/cli
  1. 创建配置
  • 官方默认配置:
shell 复制代码
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
  • 本人使用的配置:
shell 复制代码
cat > commitlint.config.js <<EOF
export default {
  extends: ['@commitlint/config-conventional'],
  'type-enum': [
    2,
    'always',
    [
      'feat',
      'fix',
      'perf',
      'style',
      'docs',
      'test',
      'refactor',
      'build',
      'ci',
      'chore',
      'revert',
      'wip',
      'workflow',
      'types',
      'release'
    ],
  ],
}
EOF

commitlint.config.js文件内容如下:

js 复制代码
export default {
  extends: ['@commitlint/config-conventional'],
  'type-enum': [
    2,
    'always',
    [
      'feat',
      'fix',
      'perf',
      'style',
      'docs',
      'test',
      'refactor',
      'build',
      'ci',
      'chore',
      'revert',
      'wip',
      'workflow',
      'types',
      'release'
    ],
  ],
}
  1. 添加git commit hook钩子

注意, 如果.git目录不是在前端项目里, 那么commit-msg也要修改进入到对应的目录, 例如:

有这样的目录结构:

bash 复制代码
. 
├── .git/ 
├── backend/ # No package.json 
└── frontend/ # Package.json with husky

那么, 对应的commit-msg文件内容就应该这样写:

bash 复制代码
cd frontend

pnpm commitlint ${1}
  • pnpm:
shell 复制代码
echo "cd frontend && pnpm commitlint --edit \$1" > .husky/commit-msg
  • npm:
shell 复制代码
echo "cd frontend && npx --no -- commitlint --edit \$1" > .husky/commit-msg

或者: 作为替代方法,在package.json 创建脚本

shell 复制代码
npm pkg set scripts.commitlint="commitlint --edit"
echo "pnpm commitlint \${1}" > .husky/commit-msg

还是那句话, 如果.git目录不是在前端项目里, 那么commit-msg也要修改进入到对应的目录

默认生成的.husky/commit-msg文件是这样:

bash 复制代码
pnpm commitlint ${1}

你需要添加:

bash 复制代码
cd frontend

...
  1. 测试

测试失败示例:

sql 复制代码
git commit -m "foo: add commit-msg hook"

预期会输出错误:

bash 复制代码
> frontend@0.0.0 commitlint /Users/lisa/Public/Golang/src/2024/edu-system/frontend
> commitlint --edit ".git/COMMIT_EDITMSG"

⧗   input: foo: add commit-msg hook
✖   type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]

✖   found 1 problems, 0 warnings
ⓘ   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

 ELIFECYCLE  Command failed with exit code 1.
husky - commit-msg script failed (code 1)

测试成功示例:

shell 复制代码
git commit -m "feat: add commit-msg hook"

配置参考

package:

sql 复制代码
pnpm add -D husky 
pnpm add -D lint-staged
pnpm add -D oxlint
pnpm create @eslint/config
pnpm add -D eslint-config-prettier eslint-plugin-prettier
pnpm add -D --save-exact prettier
pnpm add -D @commitlint/{cli,config-conventional}

package.json:

json 复制代码
{
 "lint-staged": {
    "*.{ts,tsx,js,jsx,cjs,mjs,vue}": "eslint --fix",
    "**/*": "prettier --write --ignore-unknown"
  },
"scripts": {
    "prepare": "cd .. && husky frontend/.husky",
    "prettier:check": "prettier --check src/**/**{.cjs,.mjs,.ts,.tsx,.html,.md}",
    "prettier:write": "prettier --write src/**/**{.cjs,.mjs,.ts,.tsx,.html,.md}",
    "lint": "eslint src/**/**{.ts,.tsx}",
    "lint:fix": "eslint --cache --max-warnings 0 src --ext ts,tsx --fix",
    "lint:check": "oxlint",
    "lint-staged": "lint-staged",
    "commitlint": "commitlint --edit"
  },
}

.husky/pre-commit:

bash 复制代码
cd frontend

pnpm lint-staged

.husky/commit-msg:

bash 复制代码
cd frontend

pnpm commitlint ${1}

.vscode/settings.json:

json 复制代码
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnSaveMode": "file"
}

IDE支持

VSCode

为了简化代码格式化操作,需要在VSCode保存时自动格式化代码,可以在.vscode/settings.json文件添加如下配置

shell 复制代码
mkdir -p .vscode && cat > .vscode/settings.json << EOF
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.formatOnSaveMode": "file"
}
EOF

后续文章

  1. 霞的云原生之旅: 后端工程化
  2. 霞的云原生之旅: 运维工程化

参考

  1. commitlint
  2. prettier
  3. eslint
  4. oxc
相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇6 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒6 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端