從幾次事故引起的對專案質量保障的思考

語言: CN / TW / HK

近期發生了幾件事故,第一件是封禁裝置的事故,在後臺有張頁面,只要輸入指定的裝置號,就能禁止在該手機上登入。

問題就出在這個輸入框,因為這個輸入框什麼也不填,點選按鈕,也能發起禁用的介面。

有些使用者記錄中,裝置號是空的,那麼這些記錄就會被命中,從而導致這些使用者的賬號被莫名禁用。

這麼敏感的操作,居然沒有加任何驗證限制,輕輕鬆鬆就將幾十萬的使用者封禁了,讓人甚是意外,把人家產品都嚇壞了,因為她點的這個按鈕。

第二個事故是一張榜單活動的事故,頁面沒有真實資料,而是一堆假資料。又把產品嚇壞了,一查就發現呼叫的介面居然是預發環境的。

當時是硬編碼在程式碼中,QA也發現不了,因為確實可以讀取到線上的資料。但是最近預發環境https的域名到期了,導致無法訪問,從而就發生了假資料事故。

硬編碼域名,遺留的假資料,這些都是比較細節的程式碼問題,在我看來,都是可以避免的。

這些問題雖然低階,但造成的危害可不小,如何有效的進行規避,是我近期一直在思考的事情。

一、Code Review

我首先想到的是Code Review,QA並不能幫忙驗證程式碼的問題,但是Code Review可以。

大家坐下來,一起檢查下程式碼的寫法,一起判斷業務邏輯是否合理,很容易就能發現上述兩個事故中的問題。

其實從去年開始,我就著手組織過屈指可數的幾次Code Review,是能發現些問題,但是忙碌的業務壓得我們沒有時間來做Code Review。

今年在人員補充後,工作產出大大提升,也有時間做Code Review了,並且公司環境也比較開放,上級領導不會干涉我們組內的這些非業務工作。

我們在會議中檢查的主要內容包括:

  • 是否遵循團隊的程式碼風格,例如命名是否清晰、程式碼是否冗餘等
  • 程式碼是否滿足質量特徵,例如可讀性、安全性等
  • 業務邏輯是否合理
  • 有沒有潛在的安全風險

在進行多場Code Review後,我們得到的收穫還是蠻多的,具體包括:

  • 提升程式碼質量,降低開發成本和風險,發現測試或程式碼檢查工具無法檢測到的細節問題
  • 提高、鞏固和分享開發人員的專業技能和知識概念,瞭解第三方庫的原理
  • 保障軟體開發的工藝,程式碼是一種基於知識和卓越標準的工藝
  • 互相瞭解彼此的開發特點,能更順暢的修改其他成員的程式碼

有句話叫磨刀不誤砍柴工,Code Review不僅能提升團隊的學習氛圍,而且還能提高組員們的工作效率和生產力。

在Code Review的過程中,我們也會遵循一些黃金法則,來更好更和諧的完成Code Review,具體包括:

  • 友善,清楚和具體的提問
  • 在告訴別人程式碼需要修改時,需要給出修復建議
  • 試圖理解程式碼意圖
  • 表達感謝和欣賞同事的工作

網上有些團隊是將Code Review合併到開發流程中,若未做Code Review,程式碼是無法合併到主分支的。

我們團隊,目前還並未執行這類操作,還想先再做些探索,待到Review意識比較深入時,再做打算。

二、TypeScript

TypeScript也是我在近期引入到公司的一個專案中的,目的就是想利用其強型別來更好的約束變數的使用。

在將部分元件改造成TS的語法時,也遇到了些障礙,經常需要要去google上搜索一下,很多時候需要閱讀英語資料。

首先是在將檔案字尾從 js 修改成 ts 或 tsx 後,檔案中的程式碼需要新增型別宣告,並且不能直接引入 js 檔案。

然後是引入的檔案要麼也進行改造,要麼在檔案目錄中新增 *.d.ts 宣告檔案。

  • 在使用 Ant Design 元件的屬性時,也需要宣告其型別,可以在”antd/lib/XXX“中查詢到
  • 當使用 Ant Design 元件傳遞引數時,需要傳遞必填屬性
  • 在各種函式中,需要宣告傳遞的物件引數的型別

一些沒有用ts寫的第三方 npm 模組,可以在typings.d.ts中宣告。

declare module 'query-string';
declare module 'lodash';
declare module 'react-sortable-hoc';
declare module 'papaparse';

最後還有些元件的改造,例如在底部匯出元件時,若呼叫了 Form.create(),就不能像下面這樣匯出了,在使用元件的頁面會報“has no properties in common with type 'IntrinsicAttributes”

export default connect((data: {template: TemplateModelState}) => ({state: data.template}))(Form.create()(CreateModal));

很多問題基本都是從 Github 和 StackOverflow 找到了答案,目前團隊對TS的推進還比較緩慢。

三、ESLint

在我剛出道時,開發的是.NET,當時有一款 ReSharper 驚豔到了我, 非常智慧,能自動優化我寫的糟糕程式碼。

在改寫其他語言之後,就沒遇到合適的程式碼分析工具,幾年後瞭解到 ESLint

這是一款非常有名的程式碼檢測工具,是一個組員在做團隊內部分享時,極力推薦的一款工具。

其實去年的時候,她就推薦過一次,但因為種種原因,並沒有在組內推廣。

今年的話,正好有個契機,那就是我制訂了一份專案質量保障的計劃,這款工具很適合。

先在VS Code中安裝ESLint外掛,修改配置文件。

{
  //.vue檔案template格式化支援,並使用js-beautify-html外掛
  "vetur.format.defaultFormatter.html": "js-beautify-html",
  //js-beautify-html格式化配置,屬性強制換行
  "vetur.format.defaultFormatterOptions": {
    "js-beautify-html": {
      "wrap_attributes": "force-aligned"
    }
  },
  //根據檔案字尾名定義vue檔案型別
  "files.associations": {
    "*.vue": "vue",
    "*.cjson": "jsonc",
    "*.wxss": "css",
    "*.wxs": "javascript"
  },
  //配置 ESLint 檢查的檔案型別
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "vue"
  ],
   
  "window.zoomLevel": 1,
  "diffEditor.ignoreTrimWhitespace": false,
  "explorer.confirmDelete": false,
  "editor.wordWrap": "on",
  //儲存時eslint自動修復錯誤,,並不能修復所有問題,多數還是需要手動修復
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "emmet.includeLanguages": {
    "wxml": "html"
  },
  "minapp-vscode.disableAutoConfig": true,
  "eslint.alwaysShowStatus": true,
  "eslint.debug": true,
}

然後將本地的ESLint包升級到最新版本,順便說句,原先是將依賴庫的宣告寫在了package.json中,但是線上環境node版本太低,不支援ESLint的最新版,只得先去掉依賴。

npm install eslint
npm install eslint-plugin-react
npm install eslint-plugin-jsx-a11y
npm install eslint-plugin-react-hooks
npm install eslint-config-airbnb
npm install eslint-plugin-import
npm install typescript
npm install @typescript-eslint/parser
npm install @typescript-eslint/eslint-plugin

由於之前的程式碼都沒有經過ESLint的洗禮,所以會出現大片大片的紅色波浪線,這個要習慣。

縮排好弄,儲存一下就會自動排版。還會報其他錯誤,但是在控制檯中會給出錯誤描述和線上說,點選就能跳轉,甚是方便。

ESLint的編碼風格比較嚴,很多我之前的寫法都是不允許的,例如 i++,修改函式引數,a元素必須包含href屬性等。

所以在修改程式碼的時候需要做些權衡,並不是要完全照搬這些規則,可適當的關閉。

但一些比較明顯的錯誤用法,還是需要遏制的,例如陣列的 map()需要有返回值,呼叫的方法或函式在呼叫前的位置宣告,依賴迴圈等。

ESLint對console.log會有警告提示,搜尋了一下幾個專案,遺留的console.log大概有1000多個,蠻佔用日誌的容量,也不利於日誌翻查,需要清除。

但是既不能在構建打包的時候清除,也不能直接重寫console.log,因為有些console.log是用於在 監控系統 中做除錯的。

開啟VS Code後,就發現可以全專案替換,在全域性搜尋中就有替換功能,只是之前一直沒有注意到,這次派用場了。

參考資料:

Code Reviews 101 - The Basics