從 0 到 1 搭建一個企業級前端開發規範
來源:大古同學
https://juejin.cn/post/6947872709208457253
前端代碼規範對於團隊而言至關重要,既可以提高代碼的可維護性,也可以降低代碼多人維護的成本
那如何搭建一個規範的前端項目基礎呢?接下來讓我告訴你
創建一個基礎項目
使用 npm init \-y
初始化一個前端項目, 這會自動生成package.json
文件。當我們安裝項目依賴的時候, 這個文件會自動更新
接下來我們創建以下文件目錄
└── src/
├── index.ts // 項目入口文件
├── package.json
添加 TypeScript
我們爲什麼需要 TypeScript 呢?
-
TypeScript 會在編譯代碼時,進行嚴格的靜態類型檢查。意味着可以在編碼階段發現存在的隱患,而不用把隱患帶到線上去
-
TypeScript 會包括來自 ES6 和未來提案中的特性,比如異步操作和裝飾器,也會從其他語言借鑑特性,比如接口和抽象類
-
TypeScript 編譯成 JavaScript 後,可以在任何瀏覽器 / 操作系統上運行。無需任何運行時的額外開銷
-
TypeScript 接口定義後, 可以充分利用 VSCode 的自動補全 / 自動提示功能. 因此可以直接代替文檔,同時可以提高開發效率,降低維護成本
接下來我們在 CLI 中安裝 TypeScript
yarn add typescript --dev
然後進行 TypeScript 配置!在項目根目錄通過tsc \--init
命令來創建 tsconfig.json
文件並替換爲以下內容
有關 TypeScript 的詳細配置可以查看這篇文章
{
"compilerOptions": {
"module": "esnext",
"target": "esnext",
"lib": ["esnext", "dom"],
"baseUrl": ".",
"jsx": "react-jsx",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"paths": {
"@/*": ["./src/*"]
},
"noEmit": true
},
"include": [
"src/**/*",
"typings/**/*",
"config/**/*",
".eslintrc.js",
".stylelintrc.js",
".prettierrc.js"
],
"exclude": ["node_modules", "build", "dist"]
}
在我們的React Build項目
中, 使用 Webpack 的 Babel 對項目代碼進行編譯, 因此使用 TypeScript 的唯一目的僅僅是對項目代碼進行類型檢查。
因爲 tsconfig.json
中的編譯選項僅僅針對代碼類型檢查,而不是代碼編譯, 因此不需要讓 TypeScript 生成編譯文件
以下是tsconfig.json
中一些設置的解釋
-
lib
: TS 需要引用的庫,即聲明文件,ES5 默認 dom,es5,scripthost -
allowJs
: 允許編譯 JS 文件 (js,jsx) -
allowSyntheticDefaultImports
: 允許從沒有設置默認導出的模塊中默認導入. 參考文檔 -
esModuleInterop
: 參考文檔 -
skipLibCheck
: 忽略所有的聲明文件( *.d.ts)的類型檢查 -
strict
: 開啓所有嚴格的類型檢查. 如果 strict=true, 則 所有 strict 相關的配置都應該爲 true -
forceConsistentCasingInFileNames
: 禁止對同一個文件的不一致的引用. 例如: 引用文件時大小寫必須一致 -
moduleResolution
: 使用哪種模塊解析策略. 參考文檔 -
resolveJsonModule
: 是否可以導入 JSON 模塊. 參考文檔 -
isolatedModules
: 每個文件必須是模塊. 參考文檔 -
noEmit
: 不生成輸出文件 -
jsx
: 支持 JSX. 參考文檔 -
include
: 編譯器需要編譯的文件或者目錄
添加 ESLint 代碼規範校驗
ESLint 可以幫助我們找出有問題的編碼模式或不符合規則的代碼
有關 ESLint 的詳細討論可以查看這篇文章
OK! 讓我們開始安裝 ESLint 的相關依賴
yarn add eslint eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev
以下是一些 ESLint 依賴的解釋
-
eslint
: ESLint 核心庫 -
eslint-plugin-react
: React 代碼規範的校驗規則 -
react/jsx-key
: 用來檢查是否聲明瞭 key 屬性 -
no-array-index-key
: 用來檢查是否使用了數組索引聲明 key 屬性 -
.... 其他 React 相關規範
-
eslint-plugin-react-hooks
:React hooks 代碼規範的校驗規則 -
rules-of-hooks: 用來檢查 Hook 的規則 (不能 if / 循環中使用 Hooks)
-
exhaustive-deps 規則,此規則會在
useEffct
添加錯誤依賴時發出警告並給出修復建議 -
@typescript-eslint/parser
: 將 TypeScript 代碼納入 ESLint 校驗範圍 -
@typescript-eslint/eslint-plugin
:TypeScript 代碼規範的校驗規則
在根目錄創建.eslintrc.json
文件並加入以下內容
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "react-hooks"],
"extends": [
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"react/prop-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
我們在 ESLint 配置文件中做了下面的事情
-
將
@typescript-eslint/parser
作爲 ESLint 解析器 -
使用
plugin:react/recommended
/plugin:@typescript-eslint/recommended
作爲基本規則集 -
添加了兩個 React Hooks 規則,並取消了 react/prop-types 規則, 因爲 prop 類型與 React 和 TypeScript 項目無關。
-
關閉了
explicit-module-boundary-types
,Typescript 中, 必須明確指定函數的返回值類型。並且函數中的return
後的類型必須與指定的類型一致 參考文檔
下面是一個 "explicit-module-boundary-types" 規則的栗子
// 會出現 explicit-module-boundary-types警告
export default function () {
return 1;
}
// 下面的函數不會出現警告
export var fn = function (): number {
return 1;
};
TS 中可以通過類型推斷判斷出函數的返回值類型,因此可以關閉此 Lint
添加 NPM 腳本
{
"script": {
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx ./src",
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx"
}
}
-
lint-staged:js
: 只校驗後綴名爲 ".js,.jsx,.ts,.tsx" 的文件 -
lint:js
: 只校驗src
目錄下, 後綴名爲 ".js,.jsx,.ts,.tsx" 的文件中, 被修改過的文件。這會生成一個.eslintcache
文件用來緩存已校驗過的文件 -
lint:fix
: 根據.eslintcache
文件,校驗被修改過的文件。並且自動修復
如果需要屏蔽不需要檢測的文件或目錄,可以在項目根目錄添加 .eslintignore
.DS_Store
node_modules
dist
build
public
添加 Prettier 代碼自動格式化工具
Prettier 是一個代碼格式化的工具. 某些與代碼校驗有關的規則(例如,語句末尾是否加分號)就可以由 Prettier 自動處理。
有關 Prettier 的詳細討論可以查看這篇文章
接下來我們在 CLI 中安裝 Prettier
yarn add prettier --dev
在項目根目錄新建.prettierrc
並加入以下內容
{
"printWidth": 80,
"singleQuote": true,
"semi": true,
"tabWidth": 2,
"trailingComma": "all"
}
爲VSCode
安裝 Prettier 插件
通過在 “設置” 中勾選 “保存時進行格式化” 選項, 就可以在文件保存時使用 Prettier 進行自動格式化
如果需要屏蔽不必要的文件,可以在項目根目錄添加 .prettierignore
並加入以下內容
*.svg
package.json
.DS_Store
.eslintignore
*.png
*.toml
.editorconfig
.gitignore
.prettierignore
LICENSE
.eslintcache
*.lock
yarn-error.log
/build
/public
添加 npm 腳本
"script":{
"lint:prettier": "prettier --check \"src/**/*\" --end-of-line auto",
"prettier": "prettier -c --write \"src/**/*\""
}
解釋一下腳本的含義
-
lint:prettier
: 當想要檢查文件是否已被格式化時,則可以使用--check
標誌(或-c
)運行 Prettier。這將輸出一條語義化的消息和未格式化文件的列表。上面腳本的意思是格式化src
目錄下的所有文件 -
prettier
: 重新格式化所有已被處理過的文件。類似於eslint --fix
的工作。上面腳本的意思是重新格式化src
目錄下的所有文件
添加 EditorConfig 代碼風格統一工具
EditorConfig 有助於維護跨多個編輯器和 IDE 從事同一項目的多個開發人員的一致編碼風格,團隊必備神器。
有關 EditorConfig 的詳細討論可以查看這篇文章
爲VSCode
安裝 EditorConfig 插件
在項目根目錄創建.editorconfig
並加入以下內容
# http://editorconfig.org
root = true
[*]
#縮進風格:空格
indent_style = space
#縮進大小2
indent_size = 2
#換行符lf
end_of_line = lf
#字符集utf-8
charset = utf-8
#是否刪除行尾的空格
trim_trailing_whitespace = true
#是否在文件的最後插入一個空行
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
添加 stylelint
[stylelint][https://stylelint.io/user-guide/get-started] 是一個 css 規範校驗工具,也支持 less 等 css 預處理器
有關 stylelint 的詳細討論可以查看這篇文章
爲VSCode
安裝 stylelint 插件
stylelint
安裝依賴
yarn add stylelint stylelint-config-standard --dev
新建 .stylelintrc.js
並加入以下內容
module.exports = {
extends: "stylelint-config-standard",
rules: {
// your rules
},
// 忽略其他文件,只校驗樣式相關的文件
ignoreFiles: [
"node_modules/**/*",
"public/**/*",
"dist/**/*",
"**/*.js",
"**/*.jsx",
"**/*.tsx",
"**/*.ts",
],
};
配置 NPM 腳本
"script":{
"lint:style": "stylelint --fix \"src/**/*.less\" --syntax less",
}
解釋一下腳本的含義: 自動修復src
目錄下的所有 less 文件不規範的內容
ESLint/Prettier/stylelint 工具庫推薦
推薦一個集成了 ESLint/Prettier/stylelint 的開源庫 umijs/fabric. 它把所有的常見規範都集成在了一起,而不需要開發者再去單獨維護。引用該庫的方式也很簡單
讓我們安裝該依賴
yarn add @umijs/fabric --dev
修改 ESLint/Prettier/stylelint 幾個文件的配置
// .prettierrc.js
const fabric = require("@umijs/fabric");
module.exports = {
...fabric.prettier,
};
// .stylelintrc.js
const fabric = require("@umijs/fabric");
module.exports = {
...fabric.stylelint,
};
// .eslintrc.js
module.exports = {
extends: [require.resolve("@umijs/fabric/dist/eslint")],
globals: {
// 全局變量:在全局中使用 REACT_APP_ENV時 eslint就不會出現警告
REACT_APP_ENV: true,
},
};
注: 安裝了@umijs/fabric
就不能再安裝其他 ESLint 解析器如@typescript-eslint/parser
, 否則會產生衝突
添加 Git Hook
只是單純引入代碼規範校驗如果不強制執行就等於沒做,總會有人偷懶,所以還可以加一道門檻進行約束。
我們可以通過 lint-staged
實現這道門檻: 在 git commit 命令運行時先校驗 lint(eslint, stylelint 等)是否通過,未通過則不予提交
-
husky 是一個 gitHook 工具,可以配置 git 的一些鉤子,本文主要用來配置 commit 鉤子
-
lint-staged 是一個在 git 暫存文件上運行 lint 校驗的工具,配合 husky 配置 commit 鉤子,用於 git commit 前的強制校驗
有關 Git Hook 的討論可以參考這篇文章
安裝依賴
yarn add husky lint-staged --dev
{
"scripts": {
"precommit": "lint-staged",
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"**/*.less": "stylelint --syntax less",
"**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
"**/*.{js,jsx,tsx,ts,less,md,json}": ["prettier --write"]
}
}
在每次 git commit 之前會進入工作區文件掃描,自動修復 eslint/stylelint 問題再使用 prettier 自動格式化,最後再提交到工作區。
注:
必選先使用git init
初始化 git 倉庫,之後使用 husky 才能生效
如果預提交鉤子不生效可以參考 stackoverflow:lint-staged not running on precommit
Commit Message 規範
大量的代碼提交,必然會產生大量的 Commit log. 每一條都 Commit log 記錄着某一階段所完成的事以及關注點,應該儘可能詳細具體;在工作中一份清晰規範的 Commit Message 能讓後續代碼審查、信息查找、版本回退都更加高效可靠。
Commit message 格式
<type>: <subject>
注意冒號後面有空格。
type
用於說明 commit 的類別,只允許使用下面 7 個標識。
-
feat:新功能(feature)
-
fix:修補 bug
-
docs:文檔(documentation)
-
style:格式(不影響代碼運行的變動)
-
refactor:重構(即不是新增功能,也不是修改 bug 的代碼變動)
-
test:增加測試
-
chore:構建過程或輔助工具的變動
如果 type 爲 feat 和 fix,則該 commit 將肯定出現在 Change log 之中。
subject
subject 是 commit 目的的簡短描述,不超過 50 個字符,且結尾不加句號(.)。
栗子
git commit -m 'feat:添加了一個用戶列表頁面'
git commit -m 'fix:修復用戶列表頁面無法顯示的bug'
git commit -m 'refactor:用戶列表頁面代碼重構'
這裏多一嘴: 網上有許多教程通過 commitizen 實現強制的 Commit Message 格式規範,我是不贊同的。規範應該是每個開發者自發遵循的, 如果規範過多記不住,可以通過 ESLint 等強制執行養成習慣。但對於這種簡單的規範我們應該自發遵守,更何況還有規範校驗的最後一道門檻 - 團隊代碼審查 (輕則被團隊大佬噴的體無完膚,重則捲鋪蓋走人 🙄)
參考文檔
-
一套標準的前端代碼工作流 - 掘金
-
Ant-Design-Pro
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/0-mfeSv-JVeQM_CAXeiLMQ