前端工程化一種實現方案

commit規範化方案

現階段咱們團隊的項目沒有嚴格統一的方案,爲了提升效率、規範項目,急需對開發以及提交制定好規範,特有此文。css

規範介紹以及制定

社區中的commit message規範衆多,咱們團隊選擇 Angular 規範 ,由於該規範配套工具齊全,且使用最爲普遍。html

其規範大體以下:vue

每次提交,message都應該包含三個部分:Header、Body、Footer。格式以下:java

Item Value
type(scope): subject # Header 必填,其中 type 和 subject 必填。
空一行
72-character wrapped. # Body 選填。對本次commit的詳情描述,能夠多行
空一行
BREAKING CHANGE: msg. # Footer 選填。主要用於版本回滾或綁定issue

這樣寫的commit相似於文檔或者註釋,固然若是在查看log不想所有行展現時,執行git log --oneline便可只展現一行node

Angular規範的基礎上,咱們項目須要在message前添加JIRA編號,如「AA-0000 #comment (something)」, 因此咱們最終的規範是基於Augular的規範而實現的自定義react

有了規範總不能次次手敲,能借助工具仍是要藉助工具git

commitizen

commitizen是一個格式化commit message的工具github

  • 自定義配置

cz-customizablevue-cli

  • 是一個能夠實現自定義的工具,爲了使用咱們制定的message規範,咱們須要本身實現插件

@undefined0_0/cz-customizableshell

  • 是我fork自cz-customizable的以即可以在咱們項目組中使用的工具

安裝

# commitizen工具建議全局安裝
npm i -g commitizen
# 項目級安裝
npm i -D @undefined0_0/cz-customizable
複製代碼
  • 在package.json添加配置項
// package.json
"config": {
  "commitizen": {
    "path": "./node_modules/@undefined0_0/cz-customizable"
  }
},
複製代碼

而後在項目根目錄下新建.cz-config.js文件,按照官方給的實例文件 cz-config-EXAMPLE.js 以下所示:

進行定製化修改,如去掉不使用的value,定製scope,或者漢化等等

// .cz-config.js
module.exports = {
  jiraMode: true, // 是否開啓 JIRA 校驗,默認爲false
  jiraPrefix: '', // JIRA 項目編號,會添加在需求號前,`${jiraPrefix}-0000 #comment (something)`
  types: [
    { value: 'feat', name: 'feat: A new feature' },
    { value: 'fix', name: 'fix: A bug fix' },
    { value: 'docs', name: 'docs: Documentation only changes' },
    {
      value: 'style',
      name:
        'style: Changes that do not affect the meaning of the code\n (white-space, formatting, missing semi-colons, etc)',
    },
    {
      value: 'refactor',
      name: 'refactor: A code change that neither fixes a bug nor adds a feature',
    },
    {
      value: 'perf',
      name: 'perf: A code change that improves performance',
    },
    { value: 'test', name: 'test: Adding missing tests' },
    {
      value: 'chore',
      name:
        'chore: Changes to the build process or auxiliary tools\n and libraries such as documentation generation',
    },
    { value: 'revert', name: 'revert: Revert to a commit' },
    { value: 'WIP', name: 'WIP: Work in progress' },
  ],

  scopes: [{ name: 'accounts' }, { name: 'admin' }, { name: 'exampleScope' }, { name: 'changeMe' }],

  allowTicketNumber: false,
  isTicketNumberRequired: false,
  ticketNumberPrefix: 'TICKET-',
  ticketNumberRegExp: '\\d{1,5}',

  // it needs to match the value for field type. Eg.: 'fix'
  /* scopeOverrides: { fix: [ {name: 'merge'}, {name: 'style'}, {name: 'e2eTest'}, {name: 'unitTest'} ] }, */
  // override the messages, defaults are as follows
  messages: {
    type: "Select the type of change that you're committing:",
    scope: '\nDenote the SCOPE of this change (optional):',
    // used if allowCustomScopes is true
    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):\n',
    footer: 'List any ISSUES CLOSED by this change (optional). E.g.: #31, #34:\n',
    confirmCommit: 'Are you sure you want to proceed with the commit above?',
  },

  allowCustomScopes: true,
  allowBreakingChanges: ['feat', 'fix'],
  // skip any questions you want
  skipQuestions: ['body'],

  // limit subject length
  subjectLimit: 100,
  // breaklineChar: '|', // It is supported for fields body and footer.
  // footerPrefix : 'ISSUES CLOSED:'
  // askForBreakingChangeFirst : true, // default is false
};
複製代碼

通常來講,到這一步其實已經夠用了,若是願意規範本身的代碼和commit,但若是沒有規則仍是會有錯誤的提交,接下來就繼續對commit作校驗

commitlint校驗

@commitlint/config-conventional

  • 是預設的配置

commitlint-config-cz

  • 自定義

commitlint-with-demand

  • 是爲了格式化咱們規範下的message而寫的commitlint插件

commitlint-plugin-with-jira-issue

  • 是爲了校驗咱們的message是否符合咱們的規範而寫的commitlintrule
npm i -D @commitlint/config-conventional @commitlint/cli commitlint-config-cz commitlint-with-demand commitlint-plugin-with-jira-issue
複製代碼

而後在項目根目錄新建lint配置文件.commitlintrc.js,其實別的格式也能夠。

// .commitlintrc.js
module.exports = {
  extends: [
    // 使用預設的配置
    '@commitlint/config-conventional',
    'cz'
  ],
  plugins: [
    'with-jira-issue'
  ],
  parserPreset: 'commitlint-with-demand',
  // 改變預設中的提交類型
  // rule由配置項和配置數組組成,數組中第一位爲 level 表示規則狀態,0爲禁用規則,1爲警告,2爲錯誤,第二位爲應用與否,可選 always|never ,第三位該rule的值
  rules: {
    'type-enum': [2, 'always', [
      // 只有包含以下type的message才被經過
      'feat',
      'update',
      'fix',
      // ...
    ]],
    // ...
    'with-jira-issue': [2, 'always'],
    // ...
    // 其他配置再也不贅述,移步官方文檔查看
  }
};
複製代碼
// .demand.js
// Your JIRA number
const JIRA_PROJECT = '';
module.exports = {
  JIRA_PROJECT
};
複製代碼

commitlint相關文檔

簡介

官方文檔

配置

預設配置

代碼規範

eslint

vue3用腳手架搭建項目時會自帶lint工具

或者自行安裝eslint

# eslint
npm i -D eslint babel-eslint eslint-plugin-vue
複製代碼

eslint

  • 校驗代碼的核心

babel-eslint

  • babel 插件,用 babel 解析 js 文件

eslint-plugin-vue

  • vue 官方的 eslint 插件
// package.json
"scripts": {
  "lint": "vue-cli-service lint src/**/*.js" // 不肯自動修復 帶上(--no-fix)
  // "lint": "eslint src"
}
複製代碼

.eslint.js 文件

是eslint校驗的規則,使用項目標準便可。extends 是基礎配置,rules是自定義的設置

例如

// .eslintrc.js 
module.exports = {
  // 此項是用來配置標準的js風格
  "extends": "standard",
  // add your custom rules here
  // 下面這些rules是用來設置從插件來的規範代碼的規則,使用必須去掉前綴eslint-plugin-
  // 主要有以下的設置規則,能夠設置字符串也能夠設置數字,二者效果一致
  // "off" -> 0 關閉規則
  // "warn" -> 1 開啓警告規則
  //"error" -> 2 開啓錯誤規則
  "rules": {
    "semi": [2, "never"],
    "no-console": 0,
    "comma-dangle": [2, "always-multiline"],
    "max-len": 0,
    "react/jsx-first-prop-new-line": 0,
    "react/jsx-filename-extension": 0,
    "space-before-function-paren": [2, "always"],
    "no-unused-expressions": [0, {
      "allowShortCircuit": true,
      "allowTernary": true
    }],
    "arrow-body-style": [0, "never"],
    "func-names": 0,
    "prefer-const": 0,
    "no-extend-native": 0,
    "no-param-reassign": 0,
    "no-restricted-syntax": 0,
    "no-eval": 0,
    "no-continue": 0,
    "react/jsx-no-bind": 0,
    "no-unused-vars": [2, { "ignoreRestSiblings": true }],
    "no-underscore-dangle": 0,
    "global-require": 0,
    "import/no-unresolved": 0,
    "import/extensions": 0,
    "jsx-a11y/href-no-hash": 0,
    "react/no-array-index-key": 0,
    "react/require-default-props": 0,
    "react/forbid-prop-types": 0,
    "react/no-string-refs": 0,
    "react/no-find-dom-node": 0,
    "import/no-extraneous-dependencies": 0,
    "import/prefer-default-export": 0,
    "react/no-danger": 0,
    "jsx-a11y/no-static-element-interactions": 0,
  },
  //此項是用來指定eslint解析器的,解析器必須符合規則,babel-eslint解析器是對babel解析器的包裝使其與ESLint解析
  "parser": "babel-eslint",
  //此項是用來指定javaScript語言類型和風格,sourceType用來指定js導入的方式,默認是script,此處設置爲module,指某塊導入方式
  "parserOptions": {
    "sourceType": "module",
    "ecmaVersion": 8,
    "ecmaFeatures": {
      "jsx": true,
      "experimentalObjectRestSpread": true
    }
  },
  "settings": {
    "import/resolver": "node"
  }
};
複製代碼

具體的rules見文檔

stylelint

優勢

  1. 支持lesssass預處理器;
  2. 活躍、插件多;

項目中安裝stylelint

npm i -D stylelint stylelint-config-standard stylelint-scss stylelint-order stylelint-config-recess-order
複製代碼

stylelint-scss

  • scss拓展,使stylelint支持scss語法

stylelint-config-standard

  • 官方的stylelint代碼規則

stylelint-order

  • 以某個順序編寫css。例如先寫定位,再寫盒模型,再寫內容區樣式,最後寫CSS3相關屬性。這樣能夠極大的保證咱們代碼的可讀性。

stylelint-config-recess-order

  • stylelint-order的第三方配置

配置文件.stylelintrc.js

// .stylelintrc.js
module.exports = {
  "extends": [
    "stylelint-config-standard" // 標準配置規則
  ],
  'plugins': [
    'stylelint-order', // 指定排序,好比聲明的塊內(插件包)屬性的順序。
    'stylelint-scss' // 執行各類各樣的 SCSS語法特性檢測規則(插件包)
  ],
  "rules": {
    // css書寫順序
    // ...
    // 其餘規則
    'no-empty-source': null
  }
}
複製代碼

配置文檔

中文文檔(不完整)

配置文件.stylelintignore,指定忽略的文件

*.js

*.jpg

*.woff

測試和打包目錄

/test/

/dist/
複製代碼

校驗

package.json中的scripts添加指令,而後npm run lintcss便可

// package.json
{
  "scripts": {
    "lintcss": "stylelint src/**/*.css", // (--fix) 自動修復,不建議使用
  }
}
複製代碼

Git Hooks

yorkie:在cli安裝以後,@vue/cli-service 也會安裝 yorkie,它會讓你在 package.json 的 gitHooks 字段中方便地指定 Git hook:

npm i -D lint-staged yorkie
複製代碼
// package.json
"gitHooks": {
  "pre-commit": "lint-staged", // 代碼lint檢測
  "commit-msg": "commitlint -E GIT_PARAMS" // commitlint檢測
},
複製代碼

commit-msg

  • 會在提交的時候執行,經過commitlint對相關提交信息文件進行校驗。當項目很大的時候,提交時不可能對全部文件作校驗,因此須要lint-staged對已修改的文件進行校驗

pre-commit

  • 會在提交以前執行,經過lint-staged對修改的文件進行校驗

新建.lintstagedrc.js文件

// .lintstagedrc.js
module.exports = {
  "*.{js,vue}": [
    "eslint"
  ],
  "*.{html,vue,css,wxss,sass,scss}": [
    "stylelint"
  ]
}
複製代碼

生成版本號

standard-version 是一款遵循語義化版本(semver)和 commit message 標準規範 的版本和 changelog 自動化工具。

一般咱們在main分支進行發佈操做時,須要更新版本號,更新changelog,打tag,而 standard-version 工具會自動完成上述操做

npm i -D standard-version
複製代碼
// package.json
  "scripts": {
    "release": "standard-version"
  }
複製代碼

主版本號(major):通常改動很大,不兼容低版本 次版本號(minor):兼容同一個大版本的API和用法 修訂號(patch):通常用來修復bug 有的時候在修訂號後面可能還會有先行版本號,例如1.0.0-alpha.1,1.0.0-beta.4,2.0.0-rc.1等。經常使用的先行版本通常爲alpha,beta,rc,stable,csp等。

經常使用的命令以下

-f 第一次Realease

-r 指定版本號

  • 默認狀況下,工具會自動根據 major,minor or patch 規則生成版本號,例如若是你package.json 中的version 爲 1.0.0, 那麼執行後版本號則是:1.0.1。

自定義能夠經過:

  • -r minor 執行後版本號則是:v1.1.0

  • -r 2.0.0 執行後版本號則是:v2.0.0

-p 用來生成預發版本,若是當期的版本號是 1.0.0

  • -p 執行後版本號則是:1.0.1-0
  • -p alpha 執行後版本號則是:v1.0.1-alpha.0

-t 版本 tag 前綴,默認有一個前綴v,若是不想有任何前綴,直接用-t 便可指定前綴。若是當期的版本號是 1.0.0

  • -t 'V-' 執行後版本號則是:V-2.0.0

命令能夠結合使用,如-t 'V-' -r 2.1.0,執行後版本號則是:V-2.1.0

--dry-run 預覽功能。不會修改package.json、changelog以及tag

更多命令經過 standard-version --help 查看

自定義輸出

建立.versionrc.js文件

// .versionrc.js
module.exports = {
  "header": "# HEAD \n\n", // changelog頂部標題
  "types": [ // 影響生成changelog內容的配置
      {"type": "feat", "section": "Features"},
      {"type": "fix", "section": "Bug Fixes"},
      {"type": "chore", "hidden": true},
      {"type": "docs", "hidden": true},
      {"type": "style", "hidden": true},
      {"type": "refactor", "hidden": true},
      {"type": "perf", "hidden": true},
      {"type": "test", "hidden": true}
  ],
  // ...
}
複製代碼

更多配置見Conventional Changelog Configuration Spec (v2.1.0)

生命週期腳本

standard-version支持生命週期腳本。咱們能夠經過下面這些鉤子在發佈期間去執行本身的補充命令。鉤子按照下面的順序執行:

  • prerelease:首先進入該生命週期。當prerelease返回一個非零的退出代碼,versioning將被停止,但它對進程沒有影響。

  • prebump/postbump:在版本號變動以前和以後執行。若是prebump腳本返回版本#,則將使用該版本,而不是standard-version提供的版本。

  • prechangelog/postchangelog:在生成CHANGELOG以前和以後執行。

  • precommit/postcommit:在提交步驟以前和以後調用。

  • pretag/posttag:在標記tag步驟以前和以後調用。

假如項目中使用JIRA時,issue地址須要使用jira的地址,但standard-version並不支持自定義issue地址,因此能夠這樣操做(若是安裝了replace

// .versionrc.js
  "scripts": {
    "postchangelog": "replace 'https://github.com/myproject/issues/' 'https://myjira/browse/' CHANGELOG.md"
  }
複製代碼

或者

// .versionrc.js
  "scripts": {
    "prebump": "echo 9.9.9"
  }
複製代碼

執行standard-version會生成v9.9.9的版本。

跳過特定流程

standard-version 若想跳過某些操做,如生成changelog、打tag等能夠在 .versionrc.js 文件中增長配置來實現:

// .versionrc.js
  "skip": {
    "changelog": true, // 自動生成changelog
    "commit": true, // 自動commit
    "tag": true // 打tag標識
  }
複製代碼
相關文章
相關標籤/搜索