其實ESLint + TypeScript的組合還是挺香的,代碼風格檢查 + 類型檢查,能省下不少時間。
但是還是存在一些問題。比如,有時候爲了減小打包大小,我們可能會選擇把一些不太關鍵的依賴放到CDN上,然後再通過<script>
來異步加載,這種腳本一般都會採用注入變量的方式來進行加載,這個時候就很麻煩。比如,我通過<script>
加載了d3,但是在使用的時候,就會報錯:
ESLint: 'd3' is not defined.(no-undef)
TS2686: 'd3' refers to a UMD global, but the current file is a module. Consider adding an import instead.
解決起來也還比較簡單。首先處理一下ts,給ts加一個類型聲明文件來擴展全局變量。之前我曾經寫過相關的文章,在這裏重複一下。爲了方便(並不代表應該寫成any
,只是爲了方便),在這裏就暫時用一下any
:
// shims-global.d.ts
export {};
declare global {
interface Window {
d3: any;
}
const d3: any;
}
爲什麼第一行要寫個export
?因爲ts的模塊機制,需要通過這個export
讓編譯器意識到這是一個模塊。在之前的文章裏也有相應的解釋。
然後就是配置ESLint。網上目前主要是兩種寫法:
-
直接在rules裏off掉這條規則。我覺得爲了一個變量而關掉這項檢查,不是一個很好的方案。
-
在
.eslintrc.js
里加這麼一段:module.exports = { globals: { 'echarts': true }, };
可以是可以,但是總覺得有點奇怪。爲什麼後面是個
true
呢?
所以我去查了文檔,文檔上提供了好幾種寫法,在這裏選兩個常用的:
-
通過註釋聲明,只在當前文件生效。
最簡單的寫法如下:
/* global var1, var2 */
還可以對全局變量的讀寫權限進行更細粒度的控制。寫法如下:
/* global var1:writable, var2:writable */
-
在
.eslintrc.js
進行配置,對整個項目都生效。module.exports = { globals: { var1: 'writable', var2: 'readonly' } };
在這種寫法裏,off是有特殊含義的,可以“屏蔽”原生的全局變量。比如,我不希望組裏的其他人直接使用Promise(比如
Promise.resolve
之類的方法,雖然我不知道什麼情況下我會不想讓別人用,但姑且認爲我不想讓其他人用),我就可以加上這麼一個配置:module.exports = { globals: { Promise: 'off' } };
這樣,只要試圖使用Promise,就會提示:
ESLint: 'Promise' is not defined.(no-undef)
需要注意的是,這裏不能寫成
false
,否則規則不會生效,Promise
仍然是可用的。也由此可見,寫成true
的那種寫法並沒有什麼正確性,僅僅是因爲有了一個值而已。