ESLint+Prettier+Husky+Commitlint+Stylelint+强制pnpm包前端工程代码规范

前端项目配置

记录前端项目项目配置

  1. ESLint
  2. Prettier
  3. Stylelint
  4. Husky
  5. Commitlint
  6. 强制pnpm包管理

环境准备:

  1. node:v18.16.0

  2. pnpm:v8.6.1

代码规范

代码检查工具

  • ESLint
  • Prettier
  • Stylelint

ESLint

集成

sh 复制代码
  # 安装
  pnpm i eslint -d

  # 生成配置文件
  npx eslint --init
  • 安装eslint

  • 要使用eslit做什么?

  • 项目使用的模型规范

  • 使用的框架

  • 是否使用TypeScript

  • 代码在哪里运行

  • 配置文件的类型

  • 本地的eslint没有找到,是否要下载对应的依赖

  • 选择要使用的包管理器

而在Vue3项目环境代码校验的插件还有,所以通过pnpm进行下载并创建eslintignore 文件对部分文件(dist,node_modules )进行校验忽略并重新修改.eslint.cjs配置文件

sh 复制代码
# 让所有与prettier规则存在冲突的Eslint rules失效,并使用prettier进行代码检查
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-node": "^11.1.0",
# 运行更漂亮的Eslint,使prettier规则优先级更高,Eslint优先级低
"eslint-plugin-prettier": "^4.2.1",
# vue.js的Eslint插件(查找vue语法错误,发现错误指令,查找违规风格指南
"eslint-plugin-vue": "^9.9.0",
# 该解析器允许使用Eslint校验所有babel code
"@babel/eslint-parser": "^7.19.1",

pnpm install -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node @babel/eslint-parser

这是新的.eslint.cjs配置文件,更多其他功能可以根据官方文档进行修改与配置

js 复制代码
// @see https://eslint.bootcss.com/docs/rules/

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
    jest: true,
  },
  /* 指定如何解析语法 */
  parser: 'vue-eslint-parser',
  /** 优先级低于 parse 的语法解析配置 */
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    parser: '@typescript-eslint/parser',
    jsxPragma: 'React',
    ecmaFeatures: {
      jsx: true,
    },
  },
  /* 继承已有的规则 */
  extends: [
    'eslint:recommended',
    'plugin:vue/vue3-essential',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
  ],
  plugins: ['vue', '@typescript-eslint'],
  /*
   * "off" 或 0    ==>  关闭规则
   * "warn" 或 1   ==>  打开的规则作为警告(不影响代码执行)
   * "error" 或 2  ==>  规则作为一个错误(代码不能执行,界面报错)
   */
  rules: {
    // eslint(https://eslint.bootcss.com/docs/rules/)
    'no-var': 'error', // 要求使用 let 或 const 而不是 var
    'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-unexpected-multiline': 'error', // 禁止空余的多行
    'no-useless-escape': 'off', // 禁止不必要的转义字符

    // typeScript (https://typescript-eslint.io/rules)
    '@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量
    '@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore
    '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
    '@typescript-eslint/no-non-null-assertion': 'off',
    '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
    '@typescript-eslint/semi': 'off',

    // eslint-plugin-vue (https://eslint.vuejs.org/rules/)
    'vue/multi-word-component-names': 'off', // 要求组件名称始终为 "-" 链接的单词
    'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用
    'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
    'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
  },
}

Prettier

为什么有了eslint还需要prettier?

eslint针对的是JavaScript,包含JS语法以及少部分的格式问题,但是语法正确了代码就可以运行,但是格式就是需要另外工具进行辅助使用。所以prettier主要是对代码的格式进行规范化

sh 复制代码
  # 安装依赖
  pnpm install -D eslint-plugin-prettier prettier eslint-config-prettier
  • prettierrc.json 添加规则
    *

    js 复制代码
    {
        "singleQuote": true,
        "semi": false,
        "bracketSpacing": true,
        "htmlWhitespaceSensitivity": "ignore",
        "endOfLine": "auto",
        "trailingComma": "all",
        "tabWidth": 2
      }
  • prettierrcignore 忽略文件
    *

    bash 复制代码
        /dist/*
        /html/*
        .local
        /node_modules/**
        **/*.svg
        **/*.sh
        /public/*

配置完成后需要在package.json中配置对应的运行脚本,可以通过pnpm run lint进行语法检测,通过pnpm run fix进行修改

Stylelint

stylelint为css的lint工具。可格式化css代码,检查css语法错误与不合理的写法,指定css书写顺序等。

  • 安装依赖:pnpm add sass sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order stylelint-config-standard-scss -D

  • .stylelintrc.cjs文件中编辑

    js 复制代码
      // @see https://stylelint.bootcss.com/
      module.exports = {
        extends: [
          'stylelint-config-standard', // 配置stylelint拓展插件
          'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
          'stylelint-config-standard-scss', // 配置stylelint scss插件
          'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
          'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
          'stylelint-config-prettier', // 配置stylelint和prettier兼容
        ],
        overrides: [
          {
            files: ['**/*.(scss|css|vue|html)'],
            customSyntax: 'postcss-scss',
          },
          {
            files: ['**/*.(html|vue)'],
            customSyntax: 'postcss-html',
          },
        ],
        ignoreFiles: [
          '**/*.js',
          '**/*.jsx',
          '**/*.tsx',
          '**/*.ts',
          '**/*.json',
          '**/*.md',
          '**/*.yaml',
        ],
        /**
         * null  => 关闭该规则
         * always => 必须
         */
        rules: {
          'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
          'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
          'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
          'no-empty-source': null, // 关闭禁止空源码
          'selector-class-pattern': null, // 关闭强制选择器类名的格式
          'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
          'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符
          'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
          'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
          'selector-pseudo-class-no-unknown': [
            // 不允许未知的选择器
            true,
            {
              ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
            },
          ],
        },
      }
  • .stylelintignore忽略文件

    js 复制代码
      /node_modules/*
      /dist/*
      /html/*
      /public/*
    • 最后配置统一的prettier来格式化我们的js和css,html代码

      json 复制代码
       "scripts": {
          "dev": "vite --open",
          "build": "vue-tsc && vite build",
          "preview": "vite preview",
          "lint": "eslint src",
          "fix": "eslint src --fix",
          "format": "prettier --write "./**/*.{html,vue,ts,js,json,md}"",
          "lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix",
          "lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
        },

Git相关

什么是GitHook

我们常说的Hook是钩子,根据维基百科,Hook一般指拦截软件组件或操作系统之间的通信信息,并进行处理的代码。那么对应到Git是怎样的呢?Git Hooks提供了多种形式的Hook,以pre-commit为例,该Hook将拦截git commit操作,运行名叫pre-commit的脚本,且仅当脚本返回值为0时进行真正的commit操作。

以下基于pre-commit进行讲解

为什么需要Husky

在上边已经对JS代码的检测以及规范化进行了讲解,但我们每次都是需要手动 的运行脚本才会对代码进行检测,那么我们能在每一次提交到仓库的时候都自动 的帮我们检测呢?这个时候就需要我们的Husky

利用Husky在代码提交之前触发git hook(git在客户端的钩子),然后执行pnpm run format来自动的格式化我们的代码。

相关准备

配置husky

  • 安装husky:pnpm i -d husky

  • 执行: npx huskiy-init

    sh 复制代码
    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    pnpm run format
  • 当我们对代码进行commit操作的时候,就会执行命令,对代码进行格式化,然后再提交。

配置commitlint

对于我们的commit信息,也是有统一规范的,不能随便写,要让每个人都按照统一的标准来执行,我们可以利用commitlint来实现。

  • 安装:

    sh 复制代码
    pnpm add @commitlint/config-conventional @commitlint/cli -D
  • 添加配置文件,新建commitlint.config.cjs
    *

    js 复制代码
      module.exports = {
            extends: ['@commitlint/config-conventional'],
            // 校验规则
            rules: {
              'type-enum': [
                2,
                'always',
                [
                  'feat',
                  'fix',
                  'docs',
                  'style',
                  'refactor',
                  'perf',
                  'test',
                  'chore',
                  'revert',
                  'build',
                ],
              ],
              'type-case': [0],
              'type-empty': [0],
              'scope-empty': [0],
              'scope-case': [0],
              'subject-full-stop': [0, 'never'],
              'subject-case': [0, 'never'],
              'header-max-length': [0, 'always', 72],
            },
          }
          
js 复制代码
    'feat',//新特性、新功能
    'fix',//修改bug
    'docs',//文档修改
    'style',//代码格式修改, 注意不是 css 修改
    'refactor',//代码重构
    'perf',//优化相关,比如提升性能、体验
    'test',//测试用例修改
    'chore',//其他修改, 比如改变构建流程、或者增加依赖库、工具等
    'revert',//回滚到上一个版本
    'build',//编译相关的修改,例如发布版本、对项目构建或者依赖的改动

当所有的配置完成之后,我们每一次提交都需要按照格式:git commit -m "chore: message"这样的格式去提交,这样保证了提交到仓库时信息的统一性,也便于了解目前项目进度。

  • chore: :提交时候携带的subject,注意冒号后面有空格
  • message:提交到仓库时携带的信息

强制使用pnpm包管理工具

团队开发项目的时候,需要统一包管理器工具,因为不同包管理器工具下载同一个依赖,可能版本不一样, 导致项目出现bug问题,因此包管理器工具需要统一管理

  • 在根目录创建scritps/preinstall.js文件,添加下面的内容
    *

    js 复制代码
      if (!/pnpm/.test(process.env.npm_execpath || '')) {
        console.warn(
          `\u001b[33mThis repository must using pnpm as the package manager ` +
          ` for scripts to work properly.\u001b[39m\n`,
        )
        process.exit(1)
      }
    • 当我们使用npm或者yarn来安装包的时候,就会报错了。原理就是在install的时候会触发preinstall(npm提供的生命周期钩子)这个文件里面的代码。

    • 运行脚本

环境变量配置

项目开发过程中,至少会经历开发环境测试环境生产环境 三个阶段。不同阶段请求的状态(如接口地址等)不尽相同,若手动切换接口地址是相当繁琐且易出错的。于是环境变量配置的需求就应运而生,我们只需做简单的配置,把环境状态切换的工作交给代码。

  • 开发环境(development):开发使用的环境,每位开发人员在自己的dev分支上干活,开发到一定程度,同事会合并代码,进行联调。

  • 测试环境(testing) :测试同事干活的环境啦,一般会由测试同事自己来部署,然后在此环境进行测试

  • 生产环境(production) :生产环境是指正式提供对外服务的,一般会关掉错误报告,打开错误日志。(正式提供给客户使用的环境。)

注意:一般情况下,一个环境对应一台服务器,也有的公司开发与测试环境是一台服务器!!!

项目根目录分别添加 开发、生产和测试环境的文件!

js 复制代码
# 变量必须以 VITE_ 为前缀才能暴露给外部读取,详细参考vite官方文档
NODE_ENV = 'development'
VITE_APP_TITLE = '开发环境'
VITE_APP_BASE_API = '/dev-api'

development/ prodection/ test
    开发环境/ 生产环境/ 测试环境
/dev-api/ product-api/ test-api

通过import.meta.env获取环境变量

最终文件目录结构

相关推荐
川石教育25 分钟前
Vue前端开发-slot传参
前端·vue.js·前端框架·前端开发·slot组件
新时代的弩力1 小时前
【Cesium】--viewer,entity,dataSource
前端·javascript·vue.js
余道各努力,千里自同风1 小时前
HTML5 视频 Vedio 标签详解
前端·音视频·html5
尽兴-1 小时前
Vue 中父子组件间的参数传递与方法调用
前端·javascript·vue.js·父子组件·参数传递·组件调用
JerryXZR1 小时前
Vue开发中常见优化手段总结
前端·javascript·vue.js·vue性能优化
堕落年代1 小时前
Vue3的双向数据绑定
前端·javascript·vue.js
一撮不知名的呆毛2 小时前
Ajax局部刷新,异步请求
前端·javascript·ajax
好奇的菜鸟2 小时前
Vue.js 中 v-bind 和 v-model 的用法与异同
前端·javascript·vue.js
-代号95273 小时前
【React】一、JSX的使用
前端·react.js·前端框架
uhakadotcom4 小时前
AI搜索引擎的尽头是电商?从perplexity开始卖货说起...
前端·人工智能·后端