『 文章首發於GitHub Blog 』javascript
項目一開始使用的是create-react-app建立的,配置的ESLint是用的AlloyTeam的eslint-config-alloy/react, 默認配置已經很合理了,而且每條配置都有相應的說明,只須要再根據我的喜愛修改一些rule便可,我我的修改的.eslintrc.json配置以下java
{
"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
後會直接報錯node
按理說,eject先後配置不變,只不過是將配置彈出,npm start 應該能夠直接運行,可是卻報了ESLint的錯誤。react
一開始我覺得是eslint-config-alloy/react的問題,而後從新手寫了一些配置依然會報錯,證實不是eslint-config-alloy/react的問題。google以後在一個issue發現:webpack
By default Eslint errors will raise webpack errors unless you change the config as shown above.git
也就是說,ESLint的會在發現error級別錯誤的時候觸發webpack報錯,致使編譯失敗。github
可是爲何在eject以前能經過審查的代碼在eject後就遇到error報錯了呢?web
簡單粗暴咱們直接看create-react-app文檔中關於ESLint的部分npm
If you want to enable even more accessibility rules, you can create an
.eslintrc
file in the root of your project with this content:json{ "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.
如今回想一下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級別直接報錯退出,是由於將某種rule的錯誤等級定爲error時,當出錯代碼觸發了這個rule,就意味着程序根據規則來講已經不對了,就不須要再日後進行編譯等等了。因此代碼必須先過了ESLint這關(也就是用戶本身對代碼定下的規則),才能放到babel裏去進行編譯。(具體的能夠看zakas大神關於這個問題的討論)
(我我的以前原本比較喜歡error時不退出,而後選擇性的去修改部分有問題的代碼,有些報錯的代碼就不理會等重構的時候再說。可是仔細一想其實違背了ESLint的思想,既然有warning和error的區分,那些不重要的error其實就應該定義爲warning。)
按照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
,這個坑之後仔細研究一下再來填(逃。
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
}
}]
複製代碼
遵守zakas大神的設計思路,報error的就阻止編譯,改到經過爲止,報warning的就打印出來,我的認爲這纔是正確遵守ESLint的使用方法。
將./node_modules/ESLint-loader/index.js
中的
emitter(webpack.version === 2 ? new ESLintError(messages) : messages)
複製代碼
直接註釋掉!不給ESLint傳遞任何錯誤信息,也不會返回錯誤碼了,這樣終端永遠都是 0 errors 0 warnings(誤),錯誤就只能經過編輯器的紅線提示來看了。
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) orfrontend-maven-plugin
(will fail the maven build if lint errors exist).
這位仁兄提到了關於ESLint其實並不會阻止build,只是會在遇到error時阻止像webpack-dev-server這種服務器對瀏覽器的自動刷新。