爲eject後的create-react-app配置ESLint

問題

項目一開始使用的是create-react-app建立的,配置的ESLint是用的AlloyTeam的eslint-config-alloy/react, 默認配置已經很合理了,而且每條配置都有相應的說明,只須要再根據我的喜愛修改一些rule便可,我我的修改的.eslintrc.json配置以下javascript

{
    "extends": [
        "eslint-config-alloy/react"
    ],
    "globals": {
        // 這裏填入你的項目須要的全局變量
        // 這裏值爲 false 表示這個全局變量不容許被從新賦值,好比:
        //
        // jQuery: false,
        // $: false
    },
    "rules": {
        "indent": [
            "warn",
            2,
            {
                "SwitchCase": 1,
                "flatTernaryExpressions": true
            }
        ],
        "semi": [
            "error",
            "never"
        ],
        "react/jsx-indent": [
            "warn",
            2
        ],
        "react/jsx-indent-props": [
            "warn",
            2
        ],
        "no-unused-vars": [
            "warn",
            {
                "vars": "all",
                "args": "none",
                "caughtErrors": "none"
            }
        ]
    }
}

可是在eject以後運行npm start後會直接報錯java

clipboard.png

思考

按理說,eject先後配置不變,只不過是將配置彈出,npm start 應該能夠直接運行,可是卻報了ESLint的錯誤。node

一開始我覺得是eslint-config-alloy/react的問題,而後從新手寫了一些配置依然會報錯,證實不是eslint-config-alloy/react的問題。google以後在一個issue發現:react

By default Eslint errors will raise webpack errors unless you change the config as shown above.webpack

也就是說,ESLint的會在發現error級別錯誤的時候觸發webpack報錯,致使編譯失敗。git

可是爲何在eject以前能經過審查的代碼在eject後就遇到error報錯了呢?github

簡單粗暴咱們直接看create-react-app文檔中關於ESLint的部分web

If you want to enable even more accessibility rules, you can create an .eslintrc file in the root of your project with this content:npm

{
  "extends": ["react-app", "plugin:jsx-a11y/recommended"],
  "plugins": ["jsx-a11y"]
}

However, if you are using Create React App and have not ejected, any additional rules will only be displayed in the IDE integrations, but not in the browser or the terminal.json

如今回想一下create-react-app中ESLint是如何工做的,終端有warning/error的信息,可是這個打印出來的信息的其實並非依照eslint-config-alloy/react規則,而是create-react-app的默認規則。在集成在編輯器(我用的VSCode)中的紅色波浪線功能則是根據eslint-config-alloy/react規則顯示的。

可是在eject後,編譯與波浪提示都根據eslint-config-alloy/react規則進行代碼審查,因此eject前根據默認規則審查經過的代碼在eject後並不能經過eslint-config-alloy/react的審查報了錯。(eslint-config-alloy/react規則真的很嚴格)。

ESLint的error該不應直接退出

在這裏還有一個設計思路與使用思路上的衝突:ESLint默認error級別直接報錯退出,是由於將某種rule的錯誤等級定爲error時,當出錯代碼觸發了這個rule,就意味着程序根據規則來講已經不對了,就不須要再日後進行編譯等等了。因此代碼必須先過了ESLint這關(也就是用戶本身對代碼定下的規則),才能放到babel裏去進行編譯。(具體的能夠看zakas大神關於這個問題的討論

(我我的以前原本比較喜歡error時不退出,而後選擇性的去修改部分有問題的代碼,有些報錯的代碼就不理會等重構的時候再說。可是仔細一想其實違背了ESLint的思想,既然有warning和error的區分,那些不重要的error其實就應該定義爲warning。)

eslint-loader配置問題

按照ESLint-loader的文檔

failOnError (default: false)

Loader will cause the module build to fail if there are any ESLint errors.

failOnError默認是false,按照說明應該是不會阻止build。

ESLint-loader的做者也提到(不過遠在2015年3月)

failOn* are off by default to avoid webpack to break the build for "just some linting issues". So you should not have any error/warning that break the build by default.

然而,實際上build依然失敗,具體緣由我也不清楚,有幾個issue也在反應failOnError不起做用,我猜多是ESLint-loader沒能成功的配置ESLint,這個坑之後仔細研究一下再來填(逃。

解決方案

方案1

eslint-loader的做者給出的解決方案

Like I said, you can use emitWarning: true option to force all ESLint error/warning being reported as warnings

emitWarning設爲true就能夠了,全部的error/warning信息都會打印出來,error也不會阻止編譯,簡單粗暴。

rules: [{
  enforce: 'pre',
  test: /\.jsx?$/,
  loader: 'ESLint-loader',
  options: {
    emitWarning: true
  }
}]

方案2

遵守zakas大神的設計思路,報error的就阻止編譯,改到經過爲止,報warning的就打印出來,我的認爲這纔是正確遵守ESLint的使用方法。

方案3(粗暴)

./node_modules/ESLint-loader/index.js中的

emitter(webpack.version === 2 ? new ESLintError(messages) : messages)

直接註釋掉!不給ESLint傳遞任何錯誤信息,也不會返回錯誤碼了,這樣終端永遠都是 0 errors 0 warnings(誤),錯誤就只能經過編輯器的紅線提示來看了。

tips

Also to note, the actual build still finishes and produces output. This only affects wrappers that would call webpack, such as webpack-dev-server (won't automatically reload the browser if lint errors exist) or frontend-maven-plugin (will fail the maven build if lint errors exist).

這位仁兄提到了關於ESLint其實並不會阻止build,只是會在遇到error時阻止像webpack-dev-server這種服務器對瀏覽器的自動刷新。

參考

相關文章
相關標籤/搜索