统一前端项目规范

统一前端工程规范:

宗旨:团队要规范,开发有效率

项目规范必要的插件(vue为例):

  1. Eslint (检查代码规范)
  2. Prettier (检查代码风格)
  3. husky (配置 husky 使用 git hook)
  4. lint-staged (增量式检查)
  5. commitlint (检查提交信息)
  6. commitizen (规范 Git 提交说明)
  7. editorConfig (统一编辑器(可不用))
  8. stylelint (配置 stylelint 检查 CSS 规范(可不用))
  9. 配置 node 版本限制提示

前端工程搭建:

编译器规范

  • 前端编译器统一vscode
  • vscode安装插件:eslint,prettier,stylelint

配置 node 版本限制提示

  • package.json中配置

    "engines": {
      "node": ">=16.0.0"
    }
    

配置 eslint 检查代码规范

eslint处理代码规范,prettier 处理代码风格,eslint 选择只检查错误不处理风格,这样 eslint 就不会和 prettier冲突

  • 安装插件: npm i eslint -D

  • 生成配置文件(或者手动创建):eslint --init (如果没有eslint,可以全局安装一个然后使用 npx eslint --init)依次选择

     To check syntax and find problems  //这个选项是eslint默认选项,这样就不会和pretter起风格冲突
     JavaScript modules (import/export)
     vue
     YES
     Browser
     JSON
     Yes
     npm
    
  • 配置eslintrc.json/eslintrc.js/eslintrc.cjs 具体配置参考以下

    module.exports = {
     root: true,
     env: {   
      browser: true,
      node: true, // 因为比如配置vite的时候会使用到
      es6: true
     },
     // 指定如何解析语法
     parser: 'vue-eslint-parser',
     // 优先级低于 parse 的语法解析配置
     parserOptions: {
     	parser: '@typescript-eslint/parser',
     	ecmaVersion: 2020,
     	sourceType: 'module',
     	jsxPragma: 'React',
     	ecmaFeatures:{
     	  jsx: true
     	},
     },
     // 继承某些已有的规则
      extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
     /**
      * "off" 或 0    ==>  关闭规则
      * "warn" 或 1   ==>  打开的规则作为警告(不影响代码执行)
      * "error" 或 2  ==>  规则作为一个错误(代码不能执行,界面报错)
      */
      rules: { // eslint (http://eslint.cn/docs/rules)
        'no-var': 'error', // 要求使用 let 或 const 而不是 var
        'no-multiple-empty-lines': ['error', { max: 1 }], // 不允许多个空行
        'prefer-const': 'off', // 使用 let 关键字声明但在初始分配后从未重新分配的变量,要求使用 const
        'no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们
        'no-irregular-whitespace': '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-inferrable-types': 'off', // 可以轻松推断的显式类型可能会增加不必要的冗长
        '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。
        '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型
        '@typescript-eslint/ban-types': 'off', // 禁止使用特定类型
        '@typescript-eslint/explicit-function-return-type': 'off', // 不允许对初始化为数字、字符串或布尔值的变量或参数进行显式类型声明
        '@typescript-eslint/no-var-requires': 'off', // 不允许在 import 语句中使用 require 语句
        '@typescript-eslint/no-empty-function': 'off', // 禁止空函数
        '@typescript-eslint/no-use-before-define': 'off', // 禁止在变量定义之前使用它们
        '@typescript-eslint/ban-ts-comment': 'off', // 禁止 @ts-<directive> 使用注释或要求在指令后进行描述
        '@typescript-eslint/no-non-null-assertion': 'off', // 不允许使用后缀运算符的非空断言(!)
        '@typescript-eslint/explicit-module-boundary-types': 'off', // 要求导出函数和类的公共类方法的显式返回和参数类型
    
        // vue (https://eslint.vuejs.org/rules)
        'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用,此规则仅在启用该no-unused-vars规则时有效。
        'vue/v-slot-style': 'error', // 强制执行 v-slot 指令样式
        'vue/no-mutating-props': 'off', // 不允许组件 prop的改变
        'vue/no-v-html': 'off', // 禁止使用 v-html
        'vue/custom-event-name-casing': 'off', // 为自定义事件名称强制使用特定大小写
        'vue/attributes-order': 'off', // vue api使用顺序,强制执行属性顺序
        'vue/one-component-per-file': 'off', // 强制每个组件都应该在自己的文件中
        'vue/html-closing-bracket-newline': 'off', // 在标签的右括号之前要求或禁止换行
        'vue/max-attributes-per-line': 'off', // 强制每行的最大属性数
        'vue/multiline-html-element-content-newline': 'off', // 在多行元素的内容之前和之后需要换行符
        'vue/singleline-html-element-content-newline': 'off', // 在单行元素的内容之前和之后需要换行符
        'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式
        'vue/require-default-prop': 'off', // 此规则要求为每个 prop 为必填时,必须提供默认值
        'vue/multi-word-component-names': 'off' // 要求组件名称始终为 “-” 链接的单词
      }
    }
    
  • 工作区配置项目中.vscode>settings.json, 配置后vscode保存时会自动格式化代码风格

    {
      //自动格式化
      "editor.formatOnSave": true,
      "editor.codeActionsOnSave": {
        // 每次保存的时候将代码按照 eslint 格式进行修复
        "source.fixAll.stylelint": true
      }
    }
    
  • 工作区配置.eslintignore 在工程中创建.eslintignore文件,配置eslint过滤文件 (参考)

    *.sh
    node_modules
    *.md
    *.woff
    *.ttf
    .vscode
    .idea
    dist
    /public
    /docs
    .husky
    .local
    /bin
    /src/mock/*
    stats.html
    
  • 在package.json中配置eslint脚本

    "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src"
    

配置 prettier 检查代码风格

  • 安装插件 npm install -D prettier eslint-config-prettier eslint-plugin-prettier

  • 创建并配置.prettierrc.js/.prettierrc.json/.prettierrc.cjs(cjs此类型文件package.json type必须设置为module)文件 (主要是一些格式配置)(如下)

    module.exports = {
      // 指定最大换行长度
      printWidth: 130,
      // 缩进制表符宽度 | 空格数
      tabWidth: 2,
      // 使用制表符而不是空格缩进行 (true:制表符,false:空格)
      useTabs: false,
      // 结尾不用分号 (true:有,false:没有)
      semi: true,
      // 使用单引号 (true:单引号,false:双引号)
      singleQuote: true,
      // 在对象字面量中决定是否将属性名用引号括起来 可选值 "<as-needed|consistent|preserve>"
      quoteProps: "as-needed",
      // 在JSX中使用单引号而不是双引号 (true:单引号,false:双引号)
      jsxSingleQuote: false,
      // 多行时尽可能打印尾随逗号 可选值"<none|es5|all>"
      trailingComma: "none",
      // 在对象,数组括号与文字之间加空格 "{ foo: bar }" (true:有,false:没有)
      bracketSpacing: true,
      // 将 > 多行元素放在最后一行的末尾,而不是单独放在下一行 (true:放末尾,false:单独一行)
      bracketSameLine: false,
      // (x) => {} 箭头函数参数只有一个时是否要有小括号 (avoid:省略括号,always:不省略括号)
      arrowParens: "avoid",
      // 指定要使用的解析器,不需要写文件开头的 @prettier
      requirePragma: false,
      // 可以在文件顶部插入一个特殊标记,指定该文件已使用 Prettier 格式化
      insertPragma: false,
      // 用于控制文本是否应该被换行以及如何进行换行
      proseWrap: "preserve",
      // 在html中空格是否是敏感的 "css" - 遵守 CSS 显示属性的默认值, "strict" - 空格被认为是敏感的 ,"ignore" - 空格被认为是不敏感的
      htmlWhitespaceSensitivity: "css",
      // 控制在 Vue 单文件组件中 <script> 和 <style> 标签内的代码缩进方式
      vueIndentScriptAndStyle: false,
      // 换行符使用 lf 结尾是 可选值 "<auto|lf|crlf|cr>"
      endOfLine: "auto",
      // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码 (rangeStart:开始,rangeEnd:结束)
      rangeStart: 0,
      rangeEnd: Infinity
    }
    
  • 配置.prettierignore忽略文件会自动忽略node_modules

    /dist/*
    .local
    /node_modules/**
    
    **/*.svg
    **/*.sh
    
    /public/*
    stats.html
    
  • 配置.vscode> settings.josn 配置后vscode保存时会自动格式化代码风格

    {
      "editor.codeActionsOnSave": {
        // 每次保存的时候将代码按照 eslint 格式进行修复
        "source.fixAll.eslint": true
      },
      //自动格式化
      "editor.formatOnSave": true,
      //风格用prettier
      "editor.defaultFormatter": "esbenp.prettier-vscode"
    }
    
  • 在package.json中添加格式化命令

    "lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
    

Git 提交规范使用husky控制git hook

  • 安装插件:npm install --save-dev @commitlint/config-conventional @commitlint/cli

  • 在项目根目录创建commitlint.config.js/commitlint.config.cjs(cjs此类型文件package.json type必须设置为module)文件 (配置如下(可以参考插件文档))

    module.exports = {
    // 继承的规则
    extends: ['@commitlint/config-conventional'],
    // 定义规则类型
    rules: {
    // @see: https://commitlint.js.org/#/reference-rules
    // type 类型定义,表示 git 提交的 type 必须在以下类型范围内
    'type-enum': [
      2,
      'always',
      [
        'feat', // 新功能 feature
        'fix', // 修复 bug
        'docs', // 项目文档或注释变更
        'style', // 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑
        'refactor', // 代码重构,没有加新功能或者修复bug
        'perf', // 优化相关,比如提升性能、体验
        'test', // 增加测试
        'chore', // 改变构建流程、或者增加依赖库、工具等
        'revert', // 回滚到上一个版本
        'build', // 部署版本
        'ci' // 修改 CI 配置、脚本
      ]
    ],
     // subject 大小写不做校验
     'subject-case': [0]
     },
     prompt: {
        messages: {
          type: '选择你要提交的类型 :',
          scope: '选择一个提交范围(可选):',
          customScope: '请输入自定义的提交范围 :',
          subject: '填写简短精炼的变更描述 :\n',
          body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
          breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
          footerPrefixsSelect: '选择关联issue前缀(可选):',
          customFooterPrefixs: '输入自定义issue前缀 :',
          footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
          confirmCommit: '是否提交或修改commit ?'
          // 英文版本
          // type: "Select the type of change that you're committing:",
          // scope: "Denote the SCOPE of this change (optional):",
          // customScope: "Denote the SCOPE of this change:",
          // subject: "Write a SHORT, IMPERATIVE tense description of the change:\n",
          // body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
          // breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
          // footerPrefixsSelect: "Select the ISSUES type of changeList by this change (optional):",
          // customFooterPrefixs: "Input ISSUES prefix:",
          // footer: "List any ISSUES by this change. E.g.: #31, #34:\n",
          // confirmCommit: "Are you sure you want to proceed with the commit above?"
        },
        types: [
          { value: 'feat', name: '特性:   🚀  新增功能', emoji: '🚀' },
          { value: 'fix', name: '修复:   🧩  修复缺陷', emoji: '🧩' },
          { value: 'docs', name: '文档:   📚  文档变更', emoji: '📚' },
          { value: 'style', name: '格式:   🎨  代码格式(不影响功能,例如空格、分号等格式修正)', emoji: '🎨' },
          { value: 'refactor', name: '重构:   ♻️  代码重构(不包括 bug 修复、功能新增)', emoji: '♻️' },
          { value: 'perf', name: '性能:    ⚡️  性能优化', emoji: '⚡️' },
          { value: 'test', name: '测试:   ✅  添加疏漏测试或已有测试改动', emoji: '✅' },
          { value: 'build', name: '构建:   📦️  构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)', emoji: '📦️' },
          { value: 'ci', name: '集成:   🎡  修改 CI 配置、脚本', emoji: '🎡' },
          { value: 'chore', name: '回退:   ⏪️  回滚 commit', emoji: '⏪️' },
          { value: 'revert', name: '其他:   🔨  对构建过程或辅助工具和库的更改(不影响源文件、测试用例)', emoji: '🔨' },
          { value: 'wip', name: '开发:   🕔  正在开发中', emoji: '🕔' },
          { value: 'workflow', name: '工作流:   📋  工作流程改进', emoji: '📋' },
          { value: 'types', name: '类型:   🔰  类型定义文件修改', emoji: '🔰' }
        ],
        useEmoji: true,
        customScopesAlign: 'bottom',
        emptyScopesAlias: 'empty',
        customScopesAlias: 'custom',
        allowBreakingChanges: ['feat', 'fix']
       }
      };
    
  • 安装husky:npm install husky --save-dev

  • 启动hooks:npx husky install 启动后将会自动生成.husky文件夹

  • 在package.json中配置指令脚本

    "prepare": "husky install",
    
  • 运行指令:npm run prepare

  • 添加commitlint的hook到husky中 执行以下命令

    npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
    

Lint-staged增量式检查

  • 安装npm i -D lint-staged
  • 配置package.json
    "lint:lint-staged": "lint-staged",
    
  • 在根目录创建并且配置lint-staged.config.cjs/lint-staged.config.js/lint-staged.config.josn
    module.exports = {
      '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
      '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
      'package.json': ['prettier --write'],
      '*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'],
      '*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
      '*.md': ['prettier --write']
    };
    
  • 在 .husky 文件夹下的 pre-commit 中添加
    #!/usr/bin/env sh
    . "$(dirname -- "$0")/_/husky.sh"
    
    npm run lint:lint-staged
    

editorconfig统一不同编辑器的编码风格

  • 跟目录新建.editorconfig文件

  • 在文件中配置相关风格(我的配置如下)

    # @see: http://editorconfig.org
    root = true
    
    [*] # 表示所有文件适用
    charset = utf-8 # 设置文件字符集为 utf-8
    end_of_line = lf # 控制换行类型(lf | cr | crlf)
    insert_final_newline = true # 始终在文件末尾插入一个新行
    indent_style = space # 缩进风格(tab | space)
    indent_size = 2 # 缩进大小
    max_line_length = 130 # 最大行长度
    
    [*.md] # 表示仅对 md 文件适用以下规则
    max_line_length = off # 关闭最大行长度限制
    trim_trailing_whitespace = false # 关闭末尾空格修剪
    

  • 25
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值