Thus, programs must be written for people to read, and only incidentally for machines to execute

代码质量不言而喻,好代码辑清晰,阅读流通,团队协作更容易。

前置知识 AST 笼统语法树

笼统语法树 AST 是远离业务逻辑,迈向编程底层,提高个人编程能力的重要知识点。尽管 AST 的东西许多或许不会用在生产环境上,但在比如开发体会上有很大的协助。

在 vscode AST 插件体会

假如经常运用 vscode, 能够运用 vscode-ast 插件,来直观感受 JS/TS ast 分析与编辑器中代码的映射联系。

前端工程化代码质量: Linter/Format

在一个 .js 文件尝试 AST 分析:

前端工程化代码质量: Linter/Format

ast 作为底层知识,这儿仅仅介绍现在 nodejs 中常用的 JS/TS 东西:

JS解说器称号 阐明
esprima 高性能、契合规范的ECMAScript解析器
Babylon babel 的 js 解说器
espree 在acorn基础上衍生而来,eslint中运用
acorn webpack运用js解说器
astexplorer 支持多言语的 AST 在线东西(运用 codemirror 编写)
swc 根据 rust 的东西链
typescript ts 言语词法分析
@typescript-eslint/parser 在 eslint 中运用 esLint
flow js 静态类型查看
uglifyjs 压缩东西

css ast

css 解说器称号 阐明
cssom CSS解析器(不在维护状态)
csstree CSS 东西集,包含根据 W3C 规范和浏览器完成的快速详细解析器、助行器、生成器和词法分析器
postcss 用 js 编写的 css 转化东西
rework/css css 解说器

AST 根本工作流内容

  • parser 转化 language -> AST
  • walker 遍历
  • generator 遍历器
  • lexer 词法分析器

前端工程化代码质量: Linter/Format

运用 postcss 为例

读取 css 为 ast

// plugin.js
function plugin(opts = {}) {
  return {
    postcssPlugin: "transform-px-to-em",
    Declaration(decl) {
      decl.value = decl.value.replace(/px/g, "rem");
    },
  };
}
plugin.postcss = true;
export default plugin;
// transform.js
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import postcss from "postcss";
import plugin from "./plugin.js";
const __filename = fileURLToPath(import.meta.url); // file 协议转转成 绝对路径
const __dirname = path.dirname(__filename); // 获取当时文件路径
const resolvePath = (p) => path.resolve(__dirname, p);
async function init() {
  const cssCode = fs.readFileSync(resolvePath("./index.css"));
  const cssAst = await postcss([plugin])
    .process(cssCode)
    .catch((e) => {
      console.log(e);
    });
  console.log(cssAst);
  fs.writeFileSync(resolvePath("./_index.css"), cssAst.css);
}
init();
// before
div {
    padding: 0px 20px 10px 10px;
    margin: 0px; /*reset margin*/
}
// after
div {
    padding: 0rem 20rem 10rem 10rem;
    margin: 0rem; /*reset margin*/
}

Node 运用运用层面 AST 相关东西

lint 阐明
eslint js 相关 linter 东西
prettier 多文件格式化东西(主打格式功用,能够集成到 eslint 中)
editorconfig 编辑器行为束缚
stylelint 款式文件 lint 束缚,修复东西
commitlint 提交代码时 lint

lint 与 git 合作

git 功用 阐明
lint-staged 仅处理 lint-staged 的能力
git hook pre-commit 提交之前需求执行的hook
git hook commit-msg 提交信息

非 AST 东西

git 功用 阐明
esbild 核算的 esm 打包,转化等东西

VScode 插件

前端工程化代码质量: Linter/Format

  1. eslint
  2. stylelint
  3. Error Lens
  4. prettier
  5. editorconfig for VSCode

ESLint

以下示例运用 vscode 编辑器(确保 eslint 插件):

Vite + React + TS + ESLint

前端工程化代码质量: Linter/Format

// choices react-ts
pnpm create vite
// new eslint init eslint config and choice typescript
npm init @eslint/config 

主动生成.eslintrc.cjs 文件,由于是 esm 然后将其改为 .eslintrc

ESLint 装备文件示例

{
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "overrides": [
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": "latest"
    },
    "plugins": [
        "@typescript-eslint"
    ],
    "rules": {
    }
}

在 npm 脚本中增加 eslint 指令

"scripts": {
    "lint": "eslint --ext .ts,.tsx, ./src",
    "lint:fix": "eslint --ext .ts,.tsx, ./src --fix"
}

在 tsx 文件增加 const 常量修正代码会报错:

const val = 1;
val = 2;

前端工程化代码质量: Linter/Format

Prettier

大局装置 prettier 或许 项目级别 prettier, 在 ESLint 中运用 prettier 留意运用发生冲突()

Vite + React + TS + ESLint + Prettier

pnpm install prettier -D
pnpm install eslint-config-prettier eslint-plugin-prettier -D

prettier 装备文件: .prettier/.prettierignore

{
  "semi": false,
  "trailingComma": "none",
  "singleQuote": true,
  "jsxSingleQuote": true,
  "printWidth": 80,
  "tabWidth": 2
}

装备 .eslintrc 从 eslint 中发动 prettier 进行格式化,由于上面已经装置了:

  • eslint-config-prettier
  • eslint-plugin-prettier
{
    "extends": [
        "eslint:recommended",
        "plugin:@typescript-eslint/recommended",
        "plugin:prettier/recommended"
  ],
}

这样就能够在 eslint npm 脚本中发动 prettier。

StyleLint

Vite + React + TS + ESLint + Prettier + StyleLint

对款式进行 lint 和 格式化:

pnpm install stylelint -D
pnpm install stylelint-config-prettier stylelint-prettier

npm 中增加脚本:

"scripts": {
    "stylelint": "stylelint ./src/**/*.{css,less,scss,sass}",
    "stylelint:fix": "pnpm run stylelint --fix",
},

stylelint 装备文件示例

// .stylelintrc
{
  "extends": ["stylelint-prettier/recommended"]
}

当我们有一些 lint 的时候,stylelint 就会提示正在编码的你,此刻有一个很好的提示,在初期编码的你,这个更多不是束缚,而是很好的提示。

Commitlint

Vite + React + TS + ESLint + Prettier + StyleLint + Commitlint

大局运用、部分运用

// 大局
npm install -g @commitlint/cli @commitlint/config-conventional
// 部分
npm install --save-dev @commitlint/config-conventional @commitlint/cli

初始化 git

git init
touch .gitignore
# 参加
node_modules

接下来就需求合作 husky(或许其他的 git 钩子办理)合作 lint-staged。

commitlint 装备文件

echo "{ \"extends\": ['@commitlint/config-conventional'] }" > .commitlintrc

lint-staged 和 husky

lint-staged 仅仅 lint 出来 git 暂存库中得文件

pnpm install lint-staged -D

装备 lint-staged

在 package.json 中装备

{ "lint-staged": { "*": "your-cmd" } }

运用装备文件 .lintstagedrc

{
  "**/*.{ts, tsx, js, jsx}": ["npm run lint"],
  "src/**/*.{css,less,sass,scss}": ["npm run stylelint"],
  "*.md": ["prettier --write"]
}

npm 增加 lint-stated 脚本

{
   "lint-staged": "lint-staged",
}

husky 装置 + 合作 lint-staged

主动化生成 husky 相关文件

pnpm dlx husky-init && pnpm install # pnpm

增加 pre-commit/commit-msg 钩子

  • pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint-staged
  • commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit ""

提交一个“非法”的 message

git add .
git commit -m  'abc'

过错: subject-empty/type-empty 的过错提示:

前端工程化代码质量: Linter/Format

test 东西

测验也是在主动化过程中,重要的代码质量保证:

pnpm install jest ts-jest -D
  • 增加 npm 脚本(假如需求也能够增加到 lint-staged 中)
"scripts": {
    "test": "jest"
  },
  • 装备 jest
export default {
  coverageProvider: 'v8',
  preset: 'ts-jest',
  roots: ['<rootDir>/src'],
  testEnvironment: 'node',
  transform: {
    '^.+\\.tsx?$': 'ts-jest'
  }
}

提交规范东西 commitizen

两种装置方式:大局装置-项目装置

怎么提交代码?

提交行为项目不应该直接业务代码相关,推荐大局装置,写入装备文件,方便在其他的电脑切换时方便运用。

npm install -g commitizen

commitizen 运用 首先适配器(怎么修正,这儿不在讨论)

commitizen init cz-conventional-changelog --save-dev --save-exact

在大局装备文件中指定适配器

echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc

指定 git cz 指令取代提交 git commit

npm install commitizen cz-conventional-changelog -D

部分装置

部分装置装备 commitizen 装备 package.json 中

"config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }

根本完成提交一次

git add .
git commit -m 'feat: init'

提交成功。 下面是根本简单的装备.

修正业务代码,运用 git cz 提交就不需求自己手写契合要求的 commit message:

前端工程化代码质量: Linter/Format

笼统为一个指令

为了能快速的初始化 lint 东西,进一步提高功率,封装一个指令东西,一个指令主动装备这些:


https://github.com/yyong008/lints-compose.git
npm link # 本地运用
pnpm lints-compose create # 创建 link 装备文件 + 装置 npm 包
pnpm lints-compose reset # 移除装备文件

小结

  1. 要了 lint 解东西解决了哪些功用化的问题
  2. 尝试自己一点适用于自己的工程化东西
  3. 熟悉 AST, 了解底层知识服务于工程化

参考

  • Esprima 官方网站 esprima.org/
  • babel/packages/babel-parser at master github.com/babel/babel…
  • acornjs/acorn github.com/acornjs/aco…
  • eslint/espree github.com/eslint/espr…