前端工程化终极配置

45 阅读4分钟

代码检查

使用eslint + prettier + stylelint自动化代码检查,保证代码质量、代码格式和css格式的统一

代码质量检查:eslint

eslint可以对代码中的语法错误、变量未使用、代码风格不一致等问题进行检查

使用:

安裝eslint

安装相关插件:

  • eslint-plugin-vue 检查vue文件

  • eslint-plugin-prettiereslint-config-prettier 解决prettier与eslint的规则冲突

  • eslint-plugin-import 对导入导出语法的校验

  • eslint-plugin-unused-imports 自动删除未使用的导入

  • typescript-eslint/parser 解析ts语法

  • eslint-config-airbnb 使用较多的代码风格规范

配置.eslintrc.js文件

module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    'vue/setup-compiler-macros': true,
  },
  parser: 'vue-eslint-parser',
  plugins: ['@typescript-eslint', 'import', 'prettier', 'unused-imports'],
  extends: [
    'airbnb-base',
    'plugin:vue/vue3-recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
  ],
  parserOptions: {
    tsconfigRootDir: 'src',
    parser: '@typescript-eslint/parser',
    project: ['../tsconfig.json'],
    ecmaVersion: 'latest',
    sourceType: 'module',
    extraFileExtensions: ['.vue'],
    ecmaFeatures: {
      jsx: true,
      tsx: true,
    },
  },
  rules: {
    'prettier/prettier': ['error', { endOfLine: 'auto' }],
    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
    'arrow-body-style': 'off',
    'arrow-parens': ['warn', 'as-needed'],
    'brace-style': ['warn', '1tbs', { allowSingleLine: true }],
    camelcase: 0,
    'comma-dangle': ['warn', 'always-multiline'],
    complexity: 'off',
    curly: ['warn', 'multi-line'],
    'import/order': [
      'warn',
      {
        groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
        pathGroups: [
          {
            pattern: '@/**',
            group: 'internal',
          },
        ],
        'newlines-between': 'always',
        alphabetize: {
          order: 'asc',
        },
      },
    ],
    'no-bitwise': 'off',
    'no-invalid-this': 'off',
    'no-underscore-dangle': 0,
    '@typescript-eslint/no-unsafe-assignment': 'off',
    '@typescript-eslint/no-unsafe-member-access': 'off',
    '@typescript-eslint/no-unsafe-return': 'off',
    '@typescript-eslint/no-unsafe-call': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    'vue/max-attributes-per-line': 'off',
    'vue/first-attribute-linebreak': ['error', { singleline: 'beside' }],
    'vue/v-slot-style': ['error', 'shorthand'],
    'vue/html-self-closing': ['error', { html: { void: 'always' } }],
    'vue/singleline-html-element-content-newline': 'off',
    'vue/no-mutating-props': 'off',
    'vue/multiline-html-element-content-newline': 'off',
    'vue/require-default-prop': 'off',
    'vue/multi-word-component-names': 'off',
    'no-shadow': 'off',
    'no-use-before-define': 'off',
    '@typescript-eslint/no-use-before-define': 'off',
    'vue/no-setup-props-destructure': 'off',
    'unused-imports/no-unused-imports': 'warn',
    'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
    'import/prefer-default-export': 'off',
  },
};

代码风格统一:prettier

prettier专注于统一和美化代码的外观, 可以自动调整代码的缩进、换行、引号等

使用:

安裝prettier

配置.prettierrc.js

module.exports = {
  printWidth: 120, // 一行最多 120 字符
  tabWidth: 2, // 使用 2 个空格缩进
  singleQuote: true, // 使用单引号
  trailingComma: 'all', // 末尾需要有逗号
  arrowParens: 'avoid', // 箭头函数,只有一个参数的时候,不需要括号
  endOfLine: 'auto', // 换行符
  htmlWhitespaceSensitivity: 'ignore', // 忽略空白
};

css风格统一:stylelint

stylelint可以对css进行校验和自动格式化,包括换行、属性顺序等格式

使用:

安装stylelint

安装插件:

  • stylelint-config-rational-order 基础配置

  • stylelint-config-prettier 解决prettier与eslint的规则冲突

  • stylelint-orderstylelint-config-rational-order 属性书写排序

  • stylelint-config-standard-scssstylelint-config-standard-vue 处理scss

配置stylelint.config.js

module.exports = {
  plugins: ['stylelint-order', 'stylelint-scss'],
  extends: [
    'stylelint-config-standard-scss',
    'stylelint-config-prettier',
    'stylelint-config-rational-order',
    'stylelint-config-standard-vue/scss',
  ],
  rules: {
    'selector-pseudo-class-no-unknown': null,
    'selector-pseudo-element-no-unknown': null,
    'scss/at-extend-no-missing-placeholder': null,
    'declaration-block-trailing-semicolon': null,
    'selector-class-pattern': null,
    'custom-property-empty-line-before': null,
    'no-descending-specificity': null,
    'string-quotes': null,
    'declaration-block-no-duplicate-properties': [
      true,
      {
        ignore: ['consecutive-duplicates-with-different-values'],
      },
    ],
  },
};

在package.json中增加脚本:

"lint": "eslint --ext .ts,.tsx,.vue ./src",
"lint:style": "stylelint \"**/*.{css,scss,sass,vue}\"",
"lint:all": "pnpm lint && pnpm lint:style",

执行相应脚本即可对代码进行检查

配合vscode插件:

在vscode中安装扩展插件ESLint、Prettier、Stylelint后,可以对不合规范的代码报错提示,同时保存文件后可以自动格式化代码

lint-staged

通过lint-staged插件实现代码校验时只扫描暂存区的文件而不是全盘扫描

安装lint-staged

配置lint-staged.config.js

module.exports = {
  'src/**/*.{ts,tsx}': ['prettier', 'eslint --max-warnings 0'],
  'src/**/*.{scss,css}': ['prettier', 'stylelint'],
  'src/**/*.vue': ['prettier', 'eslint --max-warnings 0', 'stylelint'],
};

在package.json中添加脚本:

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

执行pnpm lint:staged后会对暂存区的文件进行代码检查

commit校验

在提交代码通常需要执行代码质量检查提交信息规范检查

husky

husky是一个git hooks管理工具,可以在提交代码时触发不同的钩子,执行不同的脚本

安装步骤:

首先安装husky;

之后在package.json中增加脚本:"prepare": "husky install",prepare时npm的一个钩子,在执行 npm install 命令时触发。配置后,当我们执行npm install时,会自动执行husky install,然后在根目录生成.husky目录

设置git hooks

pre-commit

在提交代码前执行,进行代码规范校验

在husky目录下新建pre-commit文件,添加以下内容:

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

pnpm lint:staged
commit-msg

规范git commit中的message

使用commitlint检验工具

安装@commitlint/cli@commitlint/config-conventional

根目录新建commitlint.config.js:

// commitlint.config.js
module.exports = {
  extends: ["@commitlint/config-conventional"],
  rules: [], // 可选,自定义rules,覆盖@commitlint/config-conventional的配置
};

之后再执行commit如果提交信息不符合规定则会终止提交。

使用commitizen在commit时提供带提示的交互式命令行

安装commitizen、@commitlint/cz-commitlint

在package.json中添加:

"scripts": {
    "commit": "git-cz"
},
"config": {
    "commitizen": {
      "path": "@commitlint/cz-commitlint"
    }
  }

在提交代码时,将命令git commit替换成npm commit

通过以上方式实现了代码校验和提交信息校验的功能,但有个问题需要优化:执行npm commit后会先书写提交信息,之后再对代码进行校验,如果校验失败则又要重新书写提交信息,这样会导致重复提交的烦恼

解决方案:

在husky中创建hook文件:prepare-commit-msg,这个hook在提交(commit)消息生成后,提交编辑器打开之前执行,配置:

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

if [ -n "$SKIP_PREPARE_COMMIT_MSG" ]
then
  echo 'skip-prepare-commit-msg'
else
  exec < /dev/tty && pnpm git-cz --hook || true
fi

之后不再需要使用pnpm commit,直接使用git commit,会先进行代码校验,校验通过后会触发这个钩子,然后自动执行pnpm git-cz打开交互式命令行。

如果需要使用pnpm commit命令,之前的package.json需要修改一下:

"scripts": {
    "commit": "cross-env SKIP_PREPARE_COMMIT_MSG=1 git-cz"
},

CI/CD

使用群组Runner,方便共享

编写makefile自动化构建命令

COMMIT=$(shell git rev-parse --short HEAD)
DATE=$(shell date +%Y%m%d%H%M)

install:
	pnpm install

build: 
	pnpm build

tar:
	rm -f fe-*.tar.gz && tar --exclude=".DS_Store" -zcvf fe-${DATE}-${COMMIT}.tar.gz ./dist

编写.gitlab-ci.yml

stages:
  - build

build:
  stage: build
  script:
    - make install
    - make build
    - make tar
  rules:
    - if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'main' || $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^dev.*$/
  tags:
    - dev-k8s