使用ESLint+Prettier來統一前端程式碼風格

Shenfq發表於2018-06-18

加分號還是不加分號?tab還是空格?你還在為程式碼風格與同事爭論得面紅耳赤嗎?

正文之前,先看個段子放鬆一下: 去死吧!你這個異教徒!

想起自己剛入行的時候,從svn上把程式碼checkout下來,看到同事寫的程式碼,大括號居然換行了。心中暗罵,這個人是不是個**,大括號為什麼要換行?年輕氣盛的我,居然滿腔怒火,將空行一一刪掉。 但是關於程式碼風格,我們很難區分誰對誰錯,不同的人有不同偏好,唯有強制要求才能規避爭論。

所以,團隊關於程式碼風格必須遵循兩個基本原則:

  1. 少數服從多數;
  2. 用工具統一風格。

本文將介紹,如何使用ESLint + Prettier來統一我們的前端程式碼風格。

Prettier是什麼?

首先,對應ESLint大多都很熟悉,用來進行程式碼的校驗,但是Prettier(直譯過來就是"更漂亮的"?)聽得可能就比較少了。js作為一門靈活的弱型別語言,程式碼風格千奇百怪,一千個人寫js就有一千種寫法。雖然js沒有官方推薦的程式碼規範,不過社群有些比較熱門的程式碼規範,比如standardjsairbnb。使用ESLint配合這些規範,能夠檢測出程式碼中的潛在問題,提高程式碼質量,但是並不能完全統一程式碼風格,因為這些程式碼規範的重點並不在程式碼風格上(雖然有一些限制)。

下面開始安利,Prettier。

Prettier是一個能夠完全統一你和同事程式碼風格的利器,假如你有個c++程式設計師轉行過來寫前端的同事,你發現你們程式碼風格完全不一樣,你難道要一行行去修改他的程式碼嗎,就算你真的去改,你的需求怎麼辦,所以沒有人真的願意在保持程式碼風格統一上面浪費時間。選擇Prettier能夠讓你節省出時間來寫更多的bug(不對,是修更多的bug),並且統一的程式碼風格能保證程式碼的可讀性。

看看Prettier乾的好事。

gif
gif

能支援jsx

gif

也能支援css

gif

唯一的遺憾是,暫時還不能格式化vue模版檔案中template部分。?

ESLint 與 Prettier配合使用

首先肯定是需要安裝prettier,並且你的專案中已經使用了ESLint,有eslintrc.js配置檔案。

npm i -D prettier
複製程式碼

配合ESLint檢測程式碼風格

安裝外掛:

npm i -D eslint-plugin-prettier
複製程式碼

eslint-plugin-prettier外掛會呼叫prettier對你的程式碼風格進行檢查,其原理是先使用prettier對你的程式碼進行格式化,然後與格式化之前的程式碼進行對比,如果過出現了不一致,這個地方就會被prettier進行標記。

接下來,我們需要在rules中新增,"prettier/prettier": "error",表示被prettier標記的地方丟擲錯誤資訊。

//.eslintrc.js
{
  "plugins": ["prettier"],
  "rules": {
    "prettier/prettier": "error"
  }
}
複製程式碼

藉助ESLint的autofix功能,在儲存程式碼的時候,自動將丟擲error的地方進行fix。因為我們專案是在webpack中引入eslint-loader來啟動eslint的,所以我們只要稍微修改webpack的配置,就能在啟動webpack-dev-server的時候,每次儲存程式碼同時自動對程式碼進行格式化。

const path = require('path')
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|vue)$/,
    	loader: 'eslint-loader',
    	enforce: 'pre',
    	include: [path.join(__dirname, 'src')],
    	options: {
          fix: true
    	}
      }
    ]
}
複製程式碼

如果你的eslint是直接通過cli方式啟動的,那麼只需要在後面加上fix即可,如:eslint --fix

如果與已存在的外掛衝突怎麼辦

npm i -D eslint-config-prettier
複製程式碼

通過使用eslint-config-prettier配置,能夠關閉一些不必要的或者是與prettier衝突的lint選項。這樣我們就不會看到一些error同時出現兩次。使用的時候需要確保,這個配置在extends的最後一項。

//.eslintrc.js
{
  extends: [
    'standard', //使用standard做程式碼規範
    "prettier",
  ],
}
複製程式碼

這裡有個文件,列出了會與prettier衝突的配置項。

同時使用上面兩項配置

如果你同時使用了上述的兩種配置,那麼你可以通過如下方式,簡化你的配置。

//.eslintrc.js
{
  "extends": ["plugin:prettier/recommended"]
}
複製程式碼

最後貼一下我們專案中的完整配置,是在vue-cli生成的程式碼基礎上修改的,並且使用standard做程式碼規範:

module.exports = {
  root: true,
  parserOptions: {
    parser: 'babel-eslint'
  },
  env: {
    browser: true,
    es6: true
  },
  extends: [
    // https://github.com/standard/standard/blob/master/docs/RULES-en.md
    'standard',
    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    'plugin:vue/essential',
    "plugin:prettier/recommended",
  ],
  // required to lint *.vue files
  plugins: [
    'vue'
  ],
  // add your custom rules here
  rules: {
    "prettier/prettier": "error",
    // allow async-await
    'generator-star-spacing': 'off',
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
  }
}

複製程式碼

什麼?你們專案沒有啟用ESLint

不要慌,沒有ESLint也不要怕,可以通過onchange進行程式碼的監聽,然後自動格式化程式碼。只要在package.json的scripts下新增如下程式碼,然後使用npm run format,我們就能監聽src目錄下所有的js檔案並進行格式化:

"scripts": {
  "format": "onchange 'src/**/*.js' -- prettier --write {{changed}}"
}
複製程式碼

當你想格式化的檔案不止js檔案時,也可以新增多個檔案列表。

"scripts": {
  "format": "onchange 'test/**/*.js' 'src/**/*.js' 'src/**/*.vue' -- prettier --write {{changed}}"
}
複製程式碼

當然,你也能夠在編輯器中配置對prettier的支援,具體支援哪些編輯器,請戳這裡

如何對Prettier進行配置

一共有三種方式支援對Prettier進行配置:

  1. 根目錄建立.prettierrc檔案,能夠寫入YML、JSON的配置格式,並且支援.yaml/.yml/.json/.js字尾;
  2. 根目錄建立.prettier.config.js檔案,並對外export一個物件;
  3. package.json中新建prettier屬性。

下面我們使用prettierrc.js的方式對prettier進行配置,同時講解下各個配置的作用。

module.exports = {
  "printWidth": 80, //一行的字元數,如果超過會進行換行,預設為80
  "tabWidth": 2, //一個tab代表幾個空格數,預設為80
  "useTabs": false, //是否使用tab進行縮排,預設為false,表示用空格進行縮減
  "singleQuote": false, //字串是否使用單引號,預設為false,使用雙引號
  "semi": true, //行位是否使用分號,預設為true
  "trailingComma": "none", //是否使用尾逗號,有三個可選值"<none|es5|all>"
  "bracketSpacing": true, //物件大括號直接是否有空格,預設為true,效果:{ foo: bar }
  "parser": "babylon" //程式碼的解析引擎,預設為babylon,與babel相同。
}
複製程式碼

配置大概列出了這些,還有一些其他配置可以在官方文件進行查閱。

注意一點,parser的配置項官網列出瞭如下可選項:

  • babylon
  • flow
  • typescript Since v1.4.0
  • postcss Since v1.4.0
  • json Since v1.5.0
  • graphql Since v1.5.0
  • markdown Since v1.8.0

但是如果你使用了vue的單檔案元件形式,記得將parser配置為vue,目前官方文件沒有列出來。當然如果你自己寫過AST的解析器,也可以用你自己的寫的parser: require("./my-parser")

總結

有了prettier我們在再也用羨慕隔壁寫golang的同事,儲存後就能自動format,也不用為了專案程式碼不統一和同事爭論得面紅耳赤,因為我們統一使用prettier的風格。可能剛開始有些地方你看不慣,不過不要緊,想想這麼做都是為了團隊和睦,世界和平,我們做出的犧牲都是必要的。而且prettier的樣式風格已經在很多大型開源專案中被採用,比如react、webpack、babel。

他們都在用

你看,他們都在用了,你還在等什麼,想變成異教徒被燒死嗎,還不快行動起來。更多精彩內容請看官方連結

相關文章