天天看點

vue3元件庫項目學習筆記(五):配置編碼規範

現在我們已經擁有了一個可以釋出的元件庫,但是大家都知道,現在市面上的元件庫基本上都是開源維護的或者團隊開發,獨立的開發元件庫工具,是以想要在團隊協作的時候更好的編碼,也為了使得我們的代碼更加規範,我們需要配置我們的元件庫規範,以下介紹幾個大家比較耳熟能詳的工具的配置,大家也可以選擇自己喜歡的工具進行開發:

配置Eslint

eslint 是一個非常通用的代碼品質檢查工具,可以通過配置檔案對代碼的品質進行限制和修複,我們首先還是導入依賴

因為我們是基于 vue 和 ts 的項目,我們還需要導入相關的依賴,因為 eslint 預設隻支援 js 的解析

關于 eslint 的個性化配置這裡就不多介紹了,我們隻講如何引入它,想了解規則定義的可以看相關的文檔

https://eslint.org/docs/latest/rules/

我們在 components 檔案夾下面建立一個eslint-config檔案夾,并且進行初始化 package.json ,我們将在這個項目中編寫我們全部的規則:

{
  "name": "@ls-ui/eslint-config",
  "version": "0.0.1",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "zs",
  "license": "MIT"
}
           

我們在項目中建立一個 index.js 入口檔案,作為我們 eslint 的配置檔案

const eslintRules = require('./eslint.rules');
const tsRules = require('./ts.rules');
const vueRules = require('./vue.rules');

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: ['plugin:vue/vue3-essential', 'prettier', 'plugin:@typescript-eslint/recommended'],
  overrides: [],
  parser: 'vue-eslint-parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
    parser: '@typescript-eslint/parser'
  },
  plugins: ['vue', '@typescript-eslint', 'prettier'],
  rules: {
    ...eslintRules,
    ...tsRules,
    ...vueRules
  }
};
           

之後我們分别編寫三個檔案作為我們規則的配置

  • eslint.rules.js
//eslint.rule.js
/* eslint配置規則 https://eslint.org/docs/latest/rules/ */
module.exports = {
  'prettier/prettier': 'error',
  'arrow-body-style': 'off',
  'prefer-arrow-callback': 'off',
  'no-console': 2,
  // 不允許不必要的轉義字元 https://eslint.org/docs/latest/rules/no-useless-escape
  'no-useless-escape': 'off',
  'comma-dangle': 'off',
  // 禁止使用 var https://eslint.org/docs/latest/rules/no-var#rule-details
  'no-var': 'error',
  // 使用單引号 https://eslint.org/docs/latest/rules/quotes#version
  quotes: ['error', 'single'],
  // 禁止分号 https://eslint.org/docs/latest/rules/semi#rule-details
  // semi: 'error',
  // 禁止 debugger https://eslint.org/docs/latest/rules/no-debugger#rule-details
  'no-debugger': 'error',
  // 禁止未使用的變量 https://eslint.org/docs/latest/rules/no-unused-vars#rule-details
  'no-unused-vars': 'error',
  // 不允許使用未聲明的變量 https://eslint.org/docs/latest/rules/no-undef
  'no-undef': 'off',
  // 函數括号前的空格 https://eslint.org/docs/latest/rules/space-before-function-paren
  'space-before-function-paren': 'off',
  // 禁止多個空行 https://eslint.org/docs/latest/rules/no-multiple-empty-lines#rule-details
  'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0, maxBOF: 0 }],
  // 在檔案末尾要求或禁止換行 https://eslint.org/docs/latest/rules/eol-last#rule-details
  'eol-last': 'error',
  // 禁止所有頁籤 https://eslint.org/docs/latest/rules/no-tabs#rule-details
  'no-tabs': 'error',
  'default-param-last': 'off'
};
           
  • ts.rules.js
/* ts配置規則  https://typescript-eslint.io/rules */
module.exports = {
  // 規定數組類型定義方式 https://typescript-eslint.io/rules/array-type
  '@typescript-eslint/array-type': 'error',
  // 禁止使用大寫 String、Number 定義類型 https://typescript-eslint.io/rules/ban-types
  '@typescript-eslint/ban-types': 'off', // beta
  // 不允許尾随逗号 https://typescript-eslint.io/rules/comma-dangle
  '@typescript-eslint/comma-dangle': 'error',
  // 強制使用 interface 定義類型 https://typescript-eslint.io/rules/consistent-type-definitions
  '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
  // 統一導出規則 https://typescript-eslint.io/rules/consistent-type-exports
  // '@typescript-eslint/consistent-type-exports': 'error',
  // 自定義對象類型樣式 https://typescript-eslint.io/rules/consistent-indexed-object-style
  '@typescript-eslint/consistent-indexed-object-style': ['warn', 'record'],
  // !禁止使用字尾運算符的非空斷言 https://typescript-eslint.io/rules/no-non-null-assertion/
  '@typescript-eslint/no-non-null-assertion': 'error',
  // 強制一緻地使用類型導入 https://typescript-eslint.io/rules/consistent-type-imports
  '@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports' }],
  // 禁止未使用的變量 https://typescript-eslint.io/rules/no-unused-vars
  '@typescript-eslint/no-unused-vars': 'error',
  // 不可以有 any https://typescript-eslint.io/rules/no-explicit-any/
  '@typescript-eslint/no-explicit-any': 'off',
  // 不可以有 require https://typescript-eslint.io/rules/no-var-requires/
  '@typescript-eslint/no-var-requires': 'off',
  // 帶有預設值的函數參數在最後 https://typescript-eslint.io/rules/default-param-last
  '@typescript-eslint/default-param-last': 'error',
  // 必須标記函數傳回值 https://typescript-eslint.io/rules/explicit-function-return-type
  '@typescript-eslint/explicit-function-return-type': 'off'
};
           
  • vue.rules.js
/* vue配置規則 https://eslint.vuejs.org/rules/ */
module.exports = {
  /* 禁止在模闆中使用 this https://eslint.vuejs.org/rules/this-in-template.html */
  'vue/this-in-template': 'error',
  /* 關閉名稱校驗 https://eslint.vuejs.org/rules/multi-word-component-names.html */
  'vue/multi-word-component-names': 'off',
  'vue/max-attributes-per-line': ['error', { singleline: { max: 30 }, multiline: { max: 30 } }],
  /*  元件标簽順序 https://eslint.vuejs.org/rules/component-tags-order.html */
  'vue/component-tags-order': ['error', { order: ['template', 'script', 'style'] }],
  /* 隻允許使用ts類型的script https://eslint.vuejs.org/rules/block-lang.html */
  'vue/block-lang': ['error', { script: { lang: 'ts' } }],
  /* 隻允許使用 setup script類型的文法 https://eslint.vuejs.org/rules/component-api-style.html */
  'vue/component-api-style': ['error', ['script-setup', 'composition']],
  /* 自定義事件強制使用中劃線連接配接 https://eslint.vuejs.org/rules/custom-event-name-casing.html */
  'vue/custom-event-name-casing': ['error', 'kebab-case', { ignores: [] }],
  /* 禁止使用 v-html  https://eslint.vuejs.org/rules/no-v-html.html */
  'vue/no-v-html': 'error',
  /* bind綁定時能簡寫就直接簡寫 https://eslint.vuejs.org/rules/prefer-true-attribute-shorthand.html */
  'vue/prefer-true-attribute-shorthand': 'error',
  /* 模闆中未使用的組建不允許注冊 https://eslint.vuejs.org/rules/no-unused-components.html */
  'vue/no-unused-components': 'error',
  /* 單标簽禁止改寫成雙标簽 https://eslint.vuejs.org/rules/html-self-closing.html */
  'vue/html-self-closing': 'off',
  /* 強制标簽閉合 https://eslint.vuejs.org/rules/html-end-tags.html */
  'vue/html-end-tags': 'error',
  /* 模闆縮進規則 */
  'vue/html-indent': ['error', 2, { attribute: 1, baseIndent: 1, closeBracket: 0, alignAttributesVertically: true }],
  /* 模闆中使用組建必須使用中劃線小寫形式 https://eslint.vuejs.org/rules/component-name-in-template-casing.html */
  'vue/component-name-in-template-casing': ['error', 'kebab-case', { registeredComponentsOnly: false }],
  // 對模闆中的自定義元件強制執行屬性命名樣式 https://eslint.vuejs.org/rules/attribute-hyphenation.html#vue-attribute-hyphenation
  'vue/attribute-hyphenation': 'error',
  // Prop 名稱強制使用特定大小寫 https://eslint.vuejs.org/rules/prop-name-casing.html
  'vue/prop-name-casing': 'error',
  // 強制執行 v-on 事件命名樣式 https://eslint.vuejs.org/rules/v-on-event-hyphenation.html
  'vue/v-on-event-hyphenation': 'error',
  // 不允許字段名稱重複 https://eslint.vuejs.org/rules/no-dupe-keys.html
  'vue/no-dupe-keys': 'error',
  // 禁止 v-if / v-else-if 鍊中的重複條件
  'vue/no-dupe-v-else-if': 'error',
  // 不允許重複屬性 https://eslint.vuejs.org/rules/no-duplicate-attributes.html
  'vue/no-duplicate-attributes': [
    'error',
    {
      allowCoexistClass: true,
      allowCoexistStyle: true
    }
  ],
  // 不允許 export 進入 <script setup> https://eslint.vuejs.org/rules/no-export-in-script-setup.html
  'vue/no-export-in-script-setup': 'error',
  // 不允許修改 props https://eslint.vuejs.org/rules/no-mutating-props.html
  'vue/no-mutating-props': 'error',
  // 不允許解析錯誤的 template https://eslint.vuejs.org/rules/no-parsing-error.html
  'vue/no-parsing-error': [
    'error',
    {
      'abrupt-closing-of-empty-comment': true,
      'absence-of-digits-in-numeric-character-reference': true,
      'cdata-in-html-content': true,
      'character-reference-outside-unicode-range': true,
      'control-character-in-input-stream': true,
      'control-character-reference': true,
      'eof-before-tag-name': true,
      'eof-in-cdata': true,
      'eof-in-comment': true,
      'eof-in-tag': true,
      'incorrectly-closed-comment': true,
      'incorrectly-opened-comment': true,
      'invalid-first-character-of-tag-name': true,
      'missing-attribute-value': true,
      'missing-end-tag-name': true,
      'missing-semicolon-after-character-reference': true,
      'missing-whitespace-between-attributes': true,
      'nested-comment': true,
      'noncharacter-character-reference': true,
      'noncharacter-in-input-stream': true,
      'null-character-reference': true,
      'surrogate-character-reference': true,
      'surrogate-in-input-stream': true,
      'unexpected-character-in-attribute-name': true,
      'unexpected-character-in-unquoted-attribute-value': true,
      'unexpected-equals-sign-before-attribute-name': true,
      'unexpected-null-character': true,
      'unexpected-question-mark-instead-of-tag-name': true,
      'unexpected-solidus-in-tag': true,
      'unknown-named-character-reference': true,
      'end-tag-with-attributes': true,
      'duplicate-attribute': true,
      'end-tag-with-trailing-solidus': true,
      'non-void-html-element-start-tag-with-trailing-solidus': false,
      'x-invalid-end-tag': true,
      'x-invalid-namespace': true
    }
  ],
  // 禁止使用 ref() 包裝的值作為操作數 https://eslint.vuejs.org/rules/no-ref-as-operand.html
  'vue/no-ref-as-operand': 'error',
  // 不允許在元件定義中使用保留名稱 https://eslint.vuejs.org/rules/no-ref-as-operand.html
  'vue/no-reserved-component-names': 'error',
  // 不允許覆寫保留鍵 https://eslint.vuejs.org/rules/no-reserved-keys.html
  'vue/no-reserved-keys': 'error',
  // 禁止 props 中的保留名稱 https://eslint.vuejs.org/rules/no-reserved-props.html
  'vue/no-reserved-props': [
    'error',
    {
      vueVersion: 3
    }
  ],
  // 不允許計算屬性中的副作用 https://eslint.vuejs.org/rules/no-side-effects-in-computed-properties.html
  'vue/no-side-effects-in-computed-properties': 'error',
  // 禁用key屬性<template> https://eslint.vuejs.org/rules/no-template-key.html
  'vue/no-template-key': 'error',
  // 不允許在 textarea 中寫 {{}} https://eslint.vuejs.org/rules/no-textarea-mustache.html
  'vue/no-textarea-mustache': 'error',
  // 禁止 v-for 指令或範圍屬性的未使用變量定義 https://eslint.vuejs.org/rules/no-unused-vars.html
  'vue/no-unused-vars': 'error',
  // 不允許調用計算屬性 https://eslint.vuejs.org/rules/no-use-computed-property-like-method.html
  'vue/no-use-computed-property-like-method': 'error',
  // 禁止在與 v-for 相同的元素上使用 v-if https://eslint.vuejs.org/rules/no-use-v-if-with-v-for.html
  'vue/no-use-v-if-with-v-for': [
    'error',
    {
      allowUsingIterationVar: true
    }
  ],
  // 禁止無用的屬性<template> https://eslint.vuejs.org/rules/no-useless-template-attributes.html
  'vue/no-useless-template-attributes': 'error',
  // 禁止元件上的 v-text / v-html https://eslint.vuejs.org/rules/no-v-text-v-html-on-component.html
  'vue/no-v-text-v-html-on-component': 'error',
  // 要求 prop 類型是構造函數 https://eslint.vuejs.org/rules/require-prop-type-constructor.html
  'vue/require-prop-type-constructor': 'error',
  // 強制渲染函數始終傳回值 https://eslint.vuejs.org/rules/require-render-return.html
  'vue/require-render-return': 'error',
  // V-bind:key使用v-for指令要求 https://eslint.vuejs.org/rules/require-v-for-key.html
  'vue/require-v-for-key': 'error',
  // 強制 props 預設值有效 https://eslint.vuejs.org/rules/require-valid-default-prop.html
  'vue/require-valid-default-prop': 'off',
  // 強制傳回語句存在于計算屬性中 https://eslint.vuejs.org/rules/return-in-computed-property.html
  'vue/return-in-computed-property': 'error',
  // 需要有效的屬性名稱 https://eslint.vuejs.org/rules/valid-attribute-name.html
  'vue/valid-attribute-name': 'off',
  // 強制執行有效的模闆根 https://eslint.vuejs.org/rules/valid-template-root.html
  'vue/valid-template-root': 'off',
  // 執行有效v-bind指令 https://eslint.vuejs.org/rules/valid-v-bind.html
  'vue/valid-v-bind': 'error',
  // 禁止在資料上使用不推薦使用的對象聲明 https://eslint.vuejs.org/rules/no-deprecated-data-object-declaration.htm
  'vue/no-deprecated-data-object-declaration': 'error',
  // 禁止使用已棄用 destroyed 和 beforeDestroy 生命周期挂鈎 https://eslint.vuejs.org/rules/no-deprecated-destroyed-lifecycle.html
  'vue/no-deprecated-destroyed-lifecycle': 'error',
  // 禁止使用已棄用 $listeners https://eslint.vuejs.org/rules/no-deprecated-dollar-listeners-api.html
  'vue/no-deprecated-dollar-listeners-api': 'error',
  // 禁止 <template v-for> 放置在子元素上的鍵 https://eslint.vuejs.org/rules/no-v-for-template-key-on-child.html
  'vue/no-v-for-template-key-on-child': 'error',
  // 強制從 vue 導入,而不是從 @vue/* 導入 https://eslint.vuejs.org/rules/prefer-import-from-vue.html
  'vue/prefer-import-from-vue': 'error',
  // 要求控制裡面内容的顯示 <transition> https://eslint.vuejs.org/rules/require-toggle-inside-transition.html
  'vue/require-toggle-inside-transition': 'error',
  // 執行有效v-is指令 https://eslint.vuejs.org/rules/valid-v-is.html
  'vue/valid-v-is': 'error',
  // 對元件定義名稱強制使用特定大小寫 https://eslint.vuejs.org/rules/component-definition-name-casing.htm
  'vue/component-definition-name-casing': ['error', 'PascalCase'],
  // 強制執行屬性順序 https://eslint.vuejs.org/rules/attributes-order.html
  'vue/attributes-order': [
    'error',
    {
      order: ['DEFINITION', 'LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', ['UNIQUE', 'SLOT'], 'TWO_WAY_BINDING', 'OTHER_DIRECTIVES', 'OTHER_ATTR', 'EVENTS', 'CONTENT'],
      alphabetical: false
    }
  ],
  // 在單行元素的内容之前和之後需要換行符 https://eslint.vuejs.org/rules/singleline-html-element-content-newline.html
  'vue/singleline-html-element-content-newline': 'off',
  // 需要 props 的預設值 https://eslint.vuejs.org/rules/require-default-prop.html
  'vue/require-default-prop': 'error',
  // emit 必須是已經聲名的方法 https://eslint.vuejs.org/rules/require-explicit-emits.html
  'vue/require-explicit-emits': [
    'error',
    {
      allowProps: false
    }
  ],
  // props 必須定義詳細的類型 https://eslint.vuejs.org/rules/require-prop-types.html
  'vue/require-prop-types': 'error',
  // 支援<template>中的注釋指令 https://eslint.vuejs.org/rules/comment-directive.html
  'vue/comment-directive': 'off'
};
           

之後我們回到根目錄編寫一個 .eslintrc 檔案,在這裡我們配置引入我們剛剛寫好的規則包

{
  "root": true,
  "extends": ["@ls-ui/eslint-config"]
}
           

同時我們配置一個 .eslintignore 檔案,在檔案裡配置的内容不會被檢測,一般我們将 node_modules 裡的包,打包生成的内容等資訊忽略,這個檔案的書寫規則和 git 的 .gitignore規則一緻

node_modules/*
packages/components/script/*
packages/components/coverage/*
packages/components/dist/*

           

引入 Prettier

代碼品質其實更多的是文法方面的校驗,如果想要我們的風格實作統一,比如,一行多少字,要不要分号,要不要雙引号等等這些關于代碼風格的統一需要用到

prettier

,同樣我們下載下傳它的依賴

之後我們建立配置檔案和忽略檔案,分别是

prettier.config.js

.prettierignore

檔案,具體配置可以檢視官網

https://prettier.io/docs/en/options.html#single-attribute-per-line

module.exports = {
  printWidth: 120, //最大單行長度
  tabWidth: 2, //每個縮進的空格數
  useTabs: false, //使用制表符而不是空格縮進行
  semi: true, //在語句的末尾列印分号
  vueIndentScriptAndStyle: true, //是否縮進 Vue 檔案中的代碼<script>和<style>标簽。
  singleQuote: true, //使用單引号而不是雙引号
  quoteProps: 'as-needed', //引用對象中的屬性時更改 "as-needed" "consistent" "preserve"
  bracketSpacing: true, //在對象文字中的括号之間列印空格
  trailingComma: 'none', //在對象或數組最後一個元素後面是否加逗号(在ES5中加尾逗号)
  arrowParens: 'avoid', //箭頭函數隻有一個參數的時候是否使用括号 always:使用  avoid: 省略
  insertPragma: false, //是否在檔案頭部插入一個 @format标記表示檔案已經被格式化了
  htmlWhitespaceSensitivity: 'strict', //HTML 空白敏感性 css strict ignore
  endOfLine: 'auto', //換行符使用什麼
  tslintIntegration: false //不讓ts使用prettier校驗
};
           

為了 prettier 和 eslint 同時起作用,我們還需要下載下傳一些依賴

最後我們在 package.json 裡添加幾條指令來允許我們的檢查和修複指令,第一條是運作 eslint 檢查并且修複問題,但是有些問題不能直接修複;第二條指令可以找出所有的問題,第三條指令是用 prettier 檢查并且問題格式問題:

"scripts": {
    "lint:fix": "eslint . --fix",
    "lint:eslint": "eslint .",
    "lint:prettier": "prettier --write ."
},
           

配置 stylelint

再配置了我們的 js 和 vue 代碼檢查之後,我們還希望我們的樣式會被檢查,是以我們使用 stylelint 進行配置,同樣還是導入依賴:

pnpm i stylelint -D -w
pnpm i stylelint-less -D -w
pnpm i postcss-less -D -w
pnpm i stylelint-config-standard -D -w
pnpm i stylelint-config-prettier -D -w
           

也是一樣的配置

stylelint.config.js

.stylelintignore

檔案:

具體可以參考官網 https://stylelint.io/user-guide/rules/selector-class-pattern/

module.exports = {
  root: true,
  plugins: ['stylelint-less'],
  extends: ['stylelint-config-standard', 'stylelint-config-prettier'],
  syntax: 'less',
  customSyntax: 'postcss-less',
  rules: {},
  ignoreFiles: ['**./*.js,', '**./*.ts,', '**./*.tsx,', '**./*.jsx,', '**./*.vue,']
};
           

之後添加指令,如果你的結構和教程的不一樣,你需要自己修改檢查樣式的路徑 :

"scripts": {
    "lint:css": "stylelint packages/components/src/**/*.less --fix"
},
           

配置husky

husky 作用是在我們使用

git送出

的過程前後,進行一系列的

hook操作

,我們也可以了解其就是一個

git

的生命周期,我們可以在這個過程中做一些事情,然後我們就可以讓使用者送出的時候檢測一次上面的檔案命名是否有問題,如果有就阻止使用者送出代碼,除此之外我們也就可以對代碼進行校驗了,上面的

eslint

prettier

stylelint

這些工具我們都可以讓其全部檢測通過才允許使用者送出代碼,這樣一來,我們就可以保證送出到倉庫的代碼是有一定可靠性的

我們還是首先下載下傳依賴:

之後我們分别執行如下的指令:

npm pkg set scripts.prepare="husky install"
npm run prepare
npx husky add .husky/pre-commit "npm test"
           

我們可以看到出現了一個 .husky 檔案夾,我們進入其中,找到 pre-commit 檔案,這個檔案就是我們可以在 git 送出之前可以運作腳本編寫的位置,我們在其中編寫一些我們剛剛編寫的指令,比如執行 eslint 的修複:

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

pnpm run lint:fix
npm test
           

之後我們可以在一些檔案裡加入一些違反我們要求的内容,比如加入一個 console 指令,然後我們送出到我們的 git 試試,如果系統阻止了你的送出,說明配置成功了

配置lint-staged

lint-staged 是一個指令行工具,它能夠對 git 的 staged(暫存區)中的檔案使用 linter 工具格式化,修複一些風格問題,并再次添加到 staged 上。他可以幫我們隻檢測本次變更的檔案,不會影響之前的檔案,這樣一來需要檢測檔案數量大大變少,還是先安裝依賴

scripts

當中去添加這樣一個腳本用于調用它:

之後編寫一個

.lintstagedrc.js

檔案用于配置我們需要的參數,這個檔案告訴了系統,說明類型的檔案需要使用什麼指令進行檢查

module.exports = {
  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
  '*.vue': ['prettier --write', 'eslint --fix'],
  'packages/components/src/**/*.less': ['stylelint --fix', 'prettier --write'],
  '*.md': ['prettier --write']
};
           

添加一些更新添加我們的腳本運作,如果沒有報錯說明你的配置成功了,在配置成功之後,我們隻需要在 husky 的配置中将我們的檢查指令換成一條統一的 lint:staged 指令就可以了

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

npm run lint:staged
npm test
           

配置commitlint

清晰指令的

commit

資訊可以幫助我們更好的溯源,也可以讓我們更加清晰的了解每次送出都變更了什麼内容,一般在開源的項目當中基本都會使用到,這樣也友善多成員對項目更快的了解。是以我們使用 commitlint 這個包來進行我們的限制,還是先下載下傳依賴:

pnpm i @commitlint/cli -D
pnpm i @commitlint/config-conventional -D
pnpm i cz-conventional-changelog -D
           

下載下傳完之後我們去完善我們的配置檔案 commitlint.config.js,還是老樣子,想要個性化定制的可以檢視 https://commitlint.js.org/#/reference-rules

module.exports = {
  ignores: [commit => commit.includes('init')],
  extends: ['@commitlint/config-conventional'],
  rules: {
    'body-leading-blank': [2, 'always'],
    'footer-leading-blank': [1, 'always'],
    'header-max-length': [2, 'always', 108],
    'subject-empty': [2, 'never'],
    'type-empty': [2, 'never'],
    'subject-case': [0]
  }
};
           

在有了配置檔案之後我們将我們的指令添加到 package.json,要注意這次需要多添加一項 “config” 的内容:

"scripts": {
    "commit": "git-cz"
  },
  "config": {
    "commitizen": {
      "path": "cz-conventional-changelog"
    }
  },
           

最後我們将送出的限制放在 husky 裡:我們在 pre-commit 的同級建立一個檔案,叫 commit-msg,然後将腳本寫入其中:

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

npx commitlint --edit $1
           

此時你可以随便送出一些内容,然後随意填寫送出資訊,發現是送出失敗的說明你配置成功了,因為你的送出資訊收到了限制,現在當你要送出内容的時候,你需要在指令行寫入以下内容:

pnpm run commit
           

運作這個腳本之後,你可以按照要求的格式建立一系列的送出資訊,這樣就可以保證協作的時候,大家的送出資訊都是規範可查的。

至此我們已經配置了我們需要的規範化代碼、樣式、代碼風格、文檔格式、送出檢查、送出資訊等一系列的内容,你可以将你的元件庫釋出到 git 上讓大家參與你的元件庫維護,讓他成為一個良好的開源項目,以下是我的連結:

https://github.com/aiai0603/ls-ui

繼續閱讀