前端工程流配置是前端工程師想要獨當一面必須掌握的一項技能,這一篇詳細講述若是一個項目從0開始搭建,會涉及到哪些規範,如何使用,配置,以及遇到的問題。總結不易,以爲有幫助能夠點贊,收藏。爲了方便下面內容的講解,我用create-react-app建立一個項目json-react-template。javascript
這裏需注意一點,create-react-app建立項目時候,已經幫你git init。本身寫腳手架的時候也能夠添加這個功能css
說到工做流不得不提eslint,它是用來檢查js/ts代碼規範的一個插件。可以幫助咱們寫出更優雅的代碼,可是不少人在使用eslint時候,每每會遇到一些問題,最大的問題就是eslint不生效,下面咱們具體來操做一下。html
在這裏咱們須要作三件事前端
1:編輯器(個人是vs code)須要安裝eslint插件vue
2:安裝eslint包java
3:引入.eslintrc文件node
前兩步比較簡單,正常操做,下面主要說說.eslintrc。不少狀況下咱們不可能記住這麼多規則,基本上到這裏都是從網上覆制一份過來。可是有時候就算是從網上copy可能也須要花費一些時間,主要是網上文章太多,選擇的時候容易對咱們形成干擾。這裏我說一個我本身以爲比較優雅的方式,在咱們的github上面,有一個git gists。這個是github提供給咱們的一個功能,可以讓咱們保留一些代碼片斷,因此咱們就能夠事先找到一份.eslintrc配置放到上面,方便後面查找(這樣從此就能夠直接去gist複製了,方向明確)。寫到這裏,我已經把以前保存的.eslintrc複製到項目裏了。 react
有了上面的配置,如今咱們來講說eslint不生效狀況,遇到這種狀況咱們該怎麼辦呢?通常三步走。webpack
1:檢查vs code是否安裝了eslint插件git
2:檢查.eslintrc規則是否正確或者相關插件是否安裝
3:重啓下編輯器
步驟1和步驟3很簡單一筆帶過,下面咱們來講一下步驟2。基本上不少eslint失效的狀況都是步驟2形成的。由於咱們是複製過來的規則,會致使有的插件沒有安裝或者因爲eslint版本緣由致使規則寫法改變(網上找的規則是eslint低版本的,可是你如今的項目是高版本)。拿我剛剛的項目舉例,如今個人vs code檢查已經失效了。
那如何檢查上面所說的第二步是否有問題呢?很簡單,執行一下eslint 讓他去檢查任意一個文件,這樣就會暴露出問題。我主要以局部安裝來講明,執行如下命令。
./node_modules/eslint/bin/eslint.js ./src/App.js
咱們能夠看到報錯說沒有找到‘airbnb-base’。查閱了一下其實對應的插件是eslint-config-airbnb-base,因此這裏的問題就是沒有安裝相關插件。我本身先安裝完,繼續執行上面的命令,又報錯以下。
繼續報錯顯示allowAfterThis這條命令不合法,說明這個eslint規則,在高版本里寫法已經改變了,我先直接把這個規則註釋掉,從新執行了一下命令。 發現eslint已經生效了,vs code開始顯示錯誤,最後咱們只要按照對應規則去更改便可。
如今再來講說.eslintignore,這個文件我以爲必定是要的。由於在打包的時候能夠減小打包速度,具體能夠看看我以前寫的這篇前端優化詳解以及須要關注的幾個問題。寫.eslintignore須要注意一點,也是不少人寫完不生效的緣由。.eslintignore的路徑前綴是/或者不寫,但不要寫./以下。
// .eslintignore
./src/__test__/*.js // 錯誤寫法 // 正確寫法 /src/__test__/*.js 或者src/__test__/*.js 複製代碼
這兩個咱們就一筆帶過,和eslint幾乎是同樣的,若是stylelint失效,請參考eslint方法解決問題。
tslint是用來檢查ts語法規範的插件,可是因爲tslint官方聲明已經不在維護了,而且推薦用eslint來檢查ts/tsx文件,因此從此使用eslint便可。那怎麼作呢?很簡單,只須要安裝一些能檢查ts的插件便可。更改一下.eslintrc配置(檢查ts的版本) 複製規則以後,若是失效,直接按照上面eslint的作法在來一遍便可。
此次來講說tsconfig.json,它的配置有不少,具體能夠看看官網www.tslang.cn/docs/handbo… 接下來選幾個項目中用到的屬性進行說明,加深一下印象。
說明:這個字段表示ts編譯後,模塊是以哪一種模塊系統存在的,主要有如下幾個'commonjs' | 'amd' | 'system' | 'umd' | 'es6' | 'es2015' | 'esnext',咱們用commonjs/es6舉例,源碼以下
export const test = (value: number) => {
console.log(value);
};
複製代碼
// commonjs編譯以下
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.test = void 0;
const test = (value) => {
console.log(value);
};
exports.test = test;
複製代碼
// es6編譯以下
export const test = (value) => {
console.log(value);
};
複製代碼
說明:這個字段表示把ts編譯成什麼樣的目標代碼es5仍是es6亦或是esnext。這個字段你們應該常常用到就不演示了。
說明:這個字段表示須要引入什麼庫,默認不寫lib字段是引入dom庫,引入dom庫是什麼意思?用直白的話說就是能夠用document這些全局的dom變量,若是你寫了lib可是沒有依賴dom,使用document的時候就會報錯,以下。
說明:allowJs這個字段意思是否容許在ts文件裏面引入js文件,checkJs表示是否檢查js錯誤。
這個主要表示將.jsx文件編譯成什麼形式,有三種形式'preserve', 'react-native', or 'react'。在react的項目裏面直接設置成react就行。
說明:這個表示當一個變量是隱式any類型的時候是否拋錯,注意這裏是隱式,不是你設置成any的。話說不清楚,直接看圖。
說明:這個表示ts會以哪一種規則去引入文件,有兩種模式'node' | 'classic',通常選擇node模式,具體規則看這個連接。
這兩個字段頗有用,一個是限制ts做用的範圍,一個是排除特殊文件,好比咱們想要編譯src下面全部ts/tsx文件,可是又不想編譯測試文件怎麼辦,能夠以下配置。
{
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"src/**/*.test.tsx"
]
}
複製代碼
生成相應的.map文件用於調試
編譯以後文件存放的目錄
自動生成相應的 '.d.ts' 文件
還有不少字段不一一列舉了,提供一個咱們常常用到的tsconfig配置,有詳細的註釋哦!
經過create-react-app建立的項目,就算使用上面的tsconfig配置,仍是會出現一個'./logo.svg'找不到的問題。這個主要是ts沒法識別這樣的模塊,因此就須要咱們本身去定義module了,格式以下。
declare module '*.svg';
複製代碼
須要注意的是這些代碼是要寫到.d.ts文件裏面。那如何讓.d.ts生效呢?大體以下,咱們能夠在tsconfig.json同級目錄下創建types文件夾,在該文件夾下建一個名爲index.d.ts的文件寫入上面代碼便可,.d.ts也是一個ts文件,因此也須要編譯才行,此時可使用include字段,以下
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"types"
],
複製代碼
commitlint以前關注的比較少一點,可是隨着工做年限的增加,愈來愈多的項目有commit提交規範,因此瞭解他是頗有必要的。我以爲如今的commit提交信息能夠分爲兩大類,一個是angular標準規範,這種規範適用於xx庫和xx插件的開發,方便生成CHANGELOG.md。另外一種就是本身寫提交規範,適用於本身公司的項目。下面按照兩種規範一一說明。
無論是標準仍是非標準,提交了commit以後,都須要作相應的檢查,對於angular規範來講有專門的配套插件幫你,它就是commitlint。咱們能夠跟着安裝下。這裏注意咱們須要安裝@commitlint/config-conventional和@commitlint/cli這兩個插件,安裝成功以後咱們應該如何去使用呢?這個時候就須要用到husky,husky插件能夠幫咱們接管git hooks,從而在相應的階段作出正確的處理。在package.json配置以下
"husky": {
"hooks": {
"commint-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
複製代碼
1:若是按照上面的寫法,husky必須是低版本,個人是4.3.8。網上的文章不少都是這種寫法,可是當我操做的時候,husky已經到了7.x版本,結果發現commtlint失效,因此若是你想要上面的配置生效,能夠和我同樣下載4.3.8,那若是非要高版本了?先等等,下面內容會說道。
2:看到上面配置你可能會蒙,-E是什麼意思,其餘字母行麼?先不要慌,從此遇到這種,咱們不要多想這確定是插件自帶的參數,因此只須要執行--help,就能夠看到其內容,以下 能夠看到-E就是"check message in the file at path given by environment variable value",翻譯出來就是「在給定的環境路徑下,檢查信息」,然後面HUSKY_GIT_PARAMS就能夠告訴husky 是檢查哪個hooks路徑。
3:咱們一直說commintlint,可是爲何插件安裝的是@commitlint/cli。咱們在npm上翻一下就知道,其實@commitlint/cli就是commitlint的別名,安裝@commitlint/cli就行,別糾結。
4:那爲何還要安裝@commitlint/config-conventional,由於commintlint只是來檢查規範的,可是具體用哪一種規範你也要定義好。就像eslint是檢查規範工具,可是咱們也要繼承airbnb這個規則了。咱們就把@commitlint/config-conventional看成airbnb便可。
5:因此你把husky版本下降你還會遇到報錯,由於你沒有指定commitlint.config.js。他是爲了告訴commitlint須要繼承哪一種規範,配置以下
module.exports = {
extends: [
'@commitlint/config-conventional'
]
};
複製代碼
6:如今提交代碼時候,就能夠看到錯誤了,以下
上面一系列的配置,可讓你在提交代碼時候,進行commit規範檢查,這個時候咱們就要按照正確的規範提交了。那怎麼樣纔算一個正確的規範了,網上有不少文章,這裏我不說的太複雜,說的太複雜的反而讓人不瞭解,具體能夠看看官網連接。大體規範以下。
<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
複製代碼
1:header部分最重要分爲type,scope,subject
type:build|ci|docs|feat|fix|perf|refactor|test
scope:表示改動的文件範圍,就是寫一下改了哪裏的模塊便可。
subject:對此次改動的具體描述,如改了什麼bug或者增長了什麼需求。
!!!注意:這裏必定要注意"feat(package.json): 增長了commintlint功能"。冒號後面必定要有一個空格哇!
2:body部分就是寫一下更詳細的描述,這個是可選的。
3:footer部分表示若是你的改動是破壞性的好比你寫的是插件,大版本升級把api都改了。須要在這裏進行詳細描述包括遷移說明。
有的人若是記不住angular書寫規範,能夠安裝這兩個插件,這兩個插件就是在你提交代碼時候自動幫你組織commit信息,不用你本身想,可是我以爲本身手寫更快點。cz-conventional-changelog這個和airbnb同樣,是和commitizen配套使用的。
1:他們兩個也有一個config配置文件,只不過咱們是寫在package.json裏面,以下
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
複製代碼
2:第二個問題因爲咱們都是局部安裝的,因此不能全局使用git cz。這個時候咱們能夠寫一個script命令來解決,提交時候就再也不是git commit而是npm run commit可能感受粗糙了點。以下
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"commit": "git-cz"
},
複製代碼
到這裏一個符合angular標準的提交規範就配置好了。
但若是咱們就不想用angular規範該怎麼辦呢?有人會說能夠設置本身的commintlint.config.js。能夠是能夠不過總以爲在他的限制範圍內,我想本身獲取到提交信息,而後根據提交的信息,用正則或者其餘規則判斷,從而給出對應的規範能夠麼?確定是能夠的。假如如今咱們作了一個產品叫xx商城,項目名爲json-shopping。這個項目中的bug和需求都有一個編號,因此咱們想要的提交規範就是"[json-shopping-123]: 修復了xxbug"。不知足這種規範統一報錯。那麼咱們該怎麼作呢?咱們參考一下vue的作法具體以下。
1:將commit-msg配置成本身的腳本
"hooks": {
"commit-msg": "node scripts/verify-commit-msg.js"
}
複製代碼
2:創建scripts文件夾,編寫verify-commit-msg.js腳本以下
const chalk = require('chalk');
const msgPath = process.env.HUSKY_GIT_PARAMS || '.git/COMMIT_EDITMSG'; // 注意由於用的是husky因此這裏是HUSKY_GIT_PARAMS
const msg = require('fs').readFileSync(msgPath, 'utf-8').trim();
const commitRE = /^\[json-shopping-\d+\]\:\s.{1,50}/;
if (!commitRE.test(msg)) {
console.log();
console.error(
chalk.red(` 提交信息不知足項目要求,具體以下\n`) +
chalk.red(` [json-shopping-xxx]: 修復xxxbug\n`) +
chalk.red(` 或者\n`) +
chalk.red(` [json-shopping-xxx]: 完成xxx需求\n`)
)
process.exit(1)
}
複製代碼
展現結果以下
寫到這裏原本不想折騰了,husky4.x版本其實已經夠用。可是無奈版本升級改動太大,本着寫文章是爲了讓本身加深印象的原則,咱們繼續來講husky高版本。husky的做用就不說了,配合hooks能夠幫咱們作許多事情。常見的hooks有pre-commit,commint-msg,pre-push。若是想知道更多hooks做用能夠查看這篇文章。好了話很少說,我先把husky升級一下。emmmmmmmm...升級完果真commitlint失效了。
高版本的husky是須要你使用.husky下面的hooks腳本,不會在本身調用.git hooks腳本,生成.husky腳本很簡單。執行命令husky install便可。可是因爲husky是局部安裝的,因此通常都是寫一個script命令,而後執行npm run prepare以下。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"prepare": "husky install"
},
複製代碼
如今咱們先按照husky官網生成一個hooks腳本,執行命令"npx husky add .husky/pre-commit "npm test""。截圖看一下 咱們發現生成了pre-commit文件,而且開頭是". "
0")/_/husky.sh""。說明咱們定義hooks腳本時候,須要在開頭帶上這句話,至於_文件夾下面的這個husky.sh文件是作什麼的,具體看這篇文章。
如今咱們知道了高版本的husky是須要本身在.husky文件夾下寫一個腳本纔會生效,那麼按照上面的例子,我寫了以下commit-msg腳本。
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
commitlint -E HUSKY_GIT_PARAMS
複製代碼
1:可是git commit以後發現沒有生效,緣由是這個腳本是不可執行的,執行以下操做chmod ug+x .husky/*,給腳本添加執行權限。
2:繼續git commit仍是有問題,由於commitlint不是全局的而且已經沒有HUSKY_GIT_PARAMS這個寫法了,須要替換成$1。因此最終改爲以下。
#!/bin/sh
. "$(dirname "$0")/_/husky. npx commitlint -e $1 複製代碼
3:若是想換成本身的commit規範,寫法以下
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
node ./scripts/verify-commit-msg.js
複製代碼
在前端工程裏面,我以爲檢查有4個方面
1:vs code編輯器檢查
2:webpack編譯檢查
3:git commit提交檢查
4:CI/CD部署檢查
只有作了這四個方面的檢查,我以爲纔是比較全的,今天咱們介紹的是vs code和git commit。可是git commit以後,正常狀況下若是這麼設置"pre-commit: eslint src/*.js",檢查的是所有文件,有點浪費性能。因此出現了lint-staged,他只會檢查咱們提交的文件,大大提升了性能,那該如何去作呢?以下
.husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
複製代碼
{
"*.js": [
"eslint --fix"
],
"*.(css|less)": [
"stylelint --fix"
]
}
複製代碼
固然前提都是要先安裝插件lint-staged。
一個完整的項目jest是必不可少的,配置jest也是典型幾步,咱們按照項目是react框架來舉例。
1:安裝jest enzyme @testing-library/react-hooks(測試hooks)插件
2:配置jest.config.js以下
module.exports = {
roots: ['<rootDir>/src'],
setupFiles: [],
clearMocks: true,
collectCoverage: true,
transform: {
'^.+\\.tsx?$': 'ts-jest'
},
// 1:解決Jest: a transform must export a `process` or `processAsync` function.
moduleNameMapper: {
'^.+\\.(css|less)$': './jest/style.transform.js'
},
transformIgnorePatterns: ['\\\\node_modules\\\\'],
globals: {
'ts-jest': {
tsConfig: './tsconfig.json'
}
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};
複製代碼
3:按照以上配置可能會出現一個"a transform must export a process
or processAsync
function."報錯,解決方法以下。建立一個jest文件夾,在該文件夾下面建立style.transform.js,內容以下
module.export = {
process() {
return '';
}
};
複製代碼
跑測試用例的時候能夠直接寫script命令而後執行,可是這裏推薦一下咱們的作法,咱們的項目是在提交以前跑測試用例,那麼該怎麼作呢?用husky高版本舉例。在.husky文件夾下面建立pre-push腳本並添加執行權限,內容以下
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run test
複製代碼
而後在編寫script命令
"scripts": {
"test": "jest"
},
複製代碼
這個配置,主要是用來格式化代碼,這裏有一個疑問,如今已經有eslint幫咱們規範格式了,爲何還要用prettier了,我以爲多是由於有的格式問題無法自動fix,並且就算自動fix那也只能在git commit的時候。對於強迫症來講,從百度搜索複製一份代碼過來,看着不少警告不及時處理有點受不了。若是添加了prettier就能夠在保存的時候自動格式化。那麼如何去作呢?以下
1:安裝vs code插件prettier
2:安裝prettier依賴包
3:配置.prettierrc
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": true,
"singleQuote": true,
"bracketSpacing": false,
"arrowParens": "avoid"
}
複製代碼
4:在vs code中的setting裏面設置,保存以後自動格式化
這是最後一個配置了,主要和angular規範一塊兒使用生成CHANGELOG.md。首先安裝conventional-changelog-cli依賴包,而後添加一個script命令便可 以下
"scripts": {
"changelog": "conventional-changelog-cli -p angular -i CHANGELOG.md -s -r 0"
},
複製代碼
爲何要寫這一篇文章,一是爲了鞏固本身的知識,讓本身有能力作一個從0搭建一個完整的項目。雖然這只是第一步規範,可是卻很重要,第二個緣由是我能夠儲備一個react模版,這樣下次再遇到react項目,就能夠直接去個人github克隆下來,快速使用。模版已經上傳,你們能夠fork,在實際的項目使用中發現問題,而且提出意見,最後用一個效果圖結束這篇文章。
tsconfig經常使用配置解析 husky6版本+commitlint使用與腳本全面分析(husky v4升級v6變化巨大)