Vue3學習筆記(八)—— Vite、ESLint

一、vite

1.1、概要

Vite(法語意爲 "快速的",發音 /vit/,發音同 "veet")是一種新型前端構建工具,能夠顯著提升前端開發體驗。它主要由兩部分組成:

Vite 意在提供開箱即用的配置,同時它的 插件 API 和 JavaScript API 帶來了高度的可擴展性,並有完整的類型支持。

本質上,webpack 是一個現代 JavaScript 應用程序的靜態模塊打包器(module bundler)

Vue 腳手架工具 vue-cli 使用 webpack 進行打包,開發時可以啓動本地開發服務器,實時預覽。因爲需要對整個項目文件進行打包,開發服務器啓動緩慢

而對於開發時文件修改後的熱更新 HMR 也存在同樣的問題

Webpack 的熱更新會以當前修改的文件爲入口重新 build 打包,所有涉及到的依賴也都會被重新加載一次

Vite 則很好地解決了上面的兩個問題

 

打包問題

vite 只啓動一臺靜態頁面的服務器,對文件代碼不打包,服務器會根據客戶端的請求加載不同的模塊處理,實現真正的按需加載

熱更新問題

vite 採用立即編譯當前修改文件的辦法。同時 vite 還會使用緩存機制( http 緩存 => vite 內置緩存 ),加載更新後的文件內容

所以,vite 具有了快速冷啓動、按需編譯、模塊熱更新等優良特質

綜上所述,vite 構建項目與 vue-cli 構建的項目在開發模式下還是有比較大的區別:

  • Vite 在開發模式下不需要打包可以直接運行,使用的是 ES6 的模塊化加載規則;Vue-CLI 開發模式下必須對項目打包纔可以運行

  • Vite 基於緩存的熱更新,Vue-CLI 基於 Webpack 的熱更新

1.2、使用vite構建第一個vue項目

方法一:

要使用 Vite 來創建一個 Vue 項目,非常簡單:

$ npm init vue@latest

這個命令會安裝和執行 create-vue,它是 Vue 提供的官方腳手架工具。跟隨命令行的提示繼續操作即可。

  • 要學習更多關於 Vite 的知識,請查看 Vite 官方文檔
  • 若要了解如何爲一個 Vite 項目配置 Vue 相關的特殊行爲,比如向 Vue 編譯器傳遞相關選項,請查看 @vitejs/plugin-vue 的文檔。

上面提到的兩種在線演練場也支持將文件作爲一個 Vite 項目下載。

方法二:

Vite 需要 Node.js 版本 14.18+,16+。然而,有些模板需要依賴更高的 Node 版本才能正常運行,當你的包管理器發出警告時,請注意升級你的 Node 版本。

使用 NPM:

$ npm create vite@latest

使用 Yarn:

$ yarn create vite

使用 PNPM:

$ pnpm create vite

 code .可以使用visual studio code打開代碼編輯窗口。

1.3、錯誤處理

1.3.1、導入自定義模塊錯誤

vite+Ts+Vue3搭建的項目中,把Ts類型文件抽離出去,再導入到頁面組件時,出現“導入路徑不能以“.ts”擴展名結束”的爆紅錯誤,但這個錯誤並不影響項目運行。

 解決方法:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
  }
})

path.resolve() 該方法將一些的 路徑/路徑段 解析爲絕對路徑。

不能解析@的問題,修改tsconfig.json文件

{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "moduleResolution": "Node",
    "strict": true,
    "jsx": "preserve",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "lib": ["ESNext", "DOM"],
    "skipLibCheck": true,
    "noEmit": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  "references": [{ "path": "./tsconfig.node.json" }]
}

增加:

    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }

1.3.2、導入內置模塊錯誤

在vite.config.ts 配置 報錯 找不到模塊“path”或其相應的類型聲明

 解決方法:

npm install @types/node --save-dev

1.3.3、找不到模塊“./App.vue”或其相應的類型聲明。ts(2307)

 

 解決方法:在vite-env.d.ts文件中增加以下聲明:

declare module '*.vue' {
      import type { DefineComponent } from 'vue';
      const vueComponent: DefineComponent<{}, {}, any>;
      export default vueComponent;
} 

1.4、配置

1.4.0、共享配置

base

  • 類型: string
  • 默認: /

開發或生產環境服務的公共基礎路徑。合法的值包括以下幾種:

  • 絕對 URL 路徑名,例如 /foo/
  • 完整的 URL,例如 https://foo.com/
  • 空字符串或 ./(用於嵌入形式的開發)

mode

  • 類型: string
  • 默認: 'development' 用於開發,'production' 用於構建

在配置中指明將會把 serve 和 build 時的模式 都 覆蓋掉。也可以通過命令行 --mode 選項來重寫。

main.ts中使用console.log(import.meta.env);查看

envDir

  • 類型: string
  • 默認: root

用於加載 .env 文件的目錄。可以是一個絕對路徑,也可以是相對於項目根的路徑。

關於環境文件的更多信息,請參見 這裏

 envDir:path.resolve(__dirname, 'config'),

.env 文件

Vite 使用 dotenv 從你的 環境目錄 中的下列文件加載額外的環境變量:

.env                # 所有情況下都會加載
.env.local          # 所有情況下都會加載,但會被 git 忽略
.env.[mode]         # 只在指定模式下加載
.env.[mode].local   # 只在指定模式下加載,但會被 git 忽略

環境加載優先級

一份用於指定模式的文件(例如 .env.production)會比通用形式的優先級更高(例如 .env)。

另外,Vite 執行時已經存在的環境變量有最高的優先級,不會被 .env 類文件覆蓋。例如當運行 VITE_SOME_KEY=123 vite build 的時候。

.env 類文件會在 Vite 啓動一開始時被加載,而改動會在重啓服務器後生效。

加載的環境變量也會通過 import.meta.env 以字符串形式暴露給客戶端源碼。

爲了防止意外地將一些環境變量泄漏到客戶端,只有以 VITE_ 爲前綴的變量纔會暴露給經過 vite 處理的代碼。例如下面這些環境變量:

VITE_SOME_KEY=123
DB_PASSWORD=foobar

只有 VITE_SOME_KEY 會被暴露爲 import.meta.env.VITE_SOME_KEY 提供給客戶端源碼,而 DB_PASSWORD 則不會。

console.log(import.meta.env.VITE_SOME_KEY) // 123
console.log(import.meta.env.DB_PASSWORD) // undefined

此外,Vite 使用 dotenv-expand 來直接拓展變量。想要了解更多相關語法,請查看 它們的文檔

請注意,如果想要在環境變量中使用 $ 符號,則必須使用 \ 對其進行轉義。

KEY=123
NEW_KEY1=test$foo   # test
NEW_KEY2=test\$foo  # test$foo
NEW_KEY3=test$KEY   # test123

如果你想自定義 env 變量的前綴,請參閱 envPrefix

安全注意事項

  • .env.*.local 文件應是本地的,可以包含敏感變量。你應該將 .local 添加到你的 .gitignore 中,以避免它們被 git 檢入。

  • 由於任何暴露給 Vite 源碼的變量最終都將出現在客戶端包中,VITE_* 變量應該不包含任何敏感信息。

1.4.1、主機與端口配置

server.host

  • 類型: string | boolean
  • 默認: 'localhost'

指定服務器應該監聽哪個 IP 地址。 如果將此設置爲 0.0.0.0 或者 true 將監聽所有地址,包括局域網和公網地址。

也可以通過 CLI 使用 --host 0.0.0.0 或 --host 來設置。

server.port

  • 類型: number
  • 默認值: 5173

指定開發服務器端口。注意:如果端口已經被使用,Vite 會自動嘗試下一個可用的端口,所以這可能不是開發服務器最終監聽的實際端口。

server.strictPort

  • 類型: boolean

設爲 true 時若端口已被佔用則會直接退出,而不是嘗試下一個可用端口。

測試無效,端口被佔用啓動不了服務器監聽程序。

1.4.2、HTTPS

超文本傳輸協議HTTP協議被用於在Web瀏覽器和網站服務器之間傳遞信息,HTTP協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此,HTTP協議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。

爲了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文本傳輸協議HTTPS,爲了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL/TLS協議,SSL/TLS依靠證書來驗證服務器的身份,併爲瀏覽器和服務器之間的通信加密。

HTTPS協議是由SSL/TLS+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,要比http協議安全

HTTPS協議的主要作用可以分爲兩種:一種是建立一個信息安全通道,來保證數據傳輸的安全;另一種就是確認網站的真實性

HTTPS和HTTP的主要區別

1、https協議需要到CA申請證書,一般免費證書較少,因而需要一定費用。

2、http是超文本傳輸協議,信息是明文傳輸,https則是具有安全性的ssl/tls加密傳輸協議。

3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,後者是443。

4、http的連接很簡單,是無狀態的;HTTPS協議是由SSL/TLS+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比http協議安全。

npm i mkcert

生成ca證書

cd [project folder]

mkdir keys

cd keys
mkcert create-ca

再根據ca證書生成cert證書

# mkcert create-cert [options] # options 參見npm文檔

# 如下,設置domains
mkcert create-cert --domains 127.0.0.1,localhost,custom1.domain.xxx,custom2.domain.xxx

安裝證書

 

 

 

 

 

 

 

 

 

 修改vite.config文件

    https: {
        cert: fs.readFileSync(path.join(__dirname, 'keys/cert.crt')),
        key: fs.readFileSync(path.join(__dirname, 'keys/cert.key')),
      },

@vitejs/plugin-basic-ssl

另一個方案比較適用的方案,就是自己本地生成證書,並且讓瀏覽器或者系統信任本地證書,項目內進行簡單的配置就可以實現訪問 https://localhost. 生成證書工具可以藉助 mkcert 或者 openssl

Vite 項目

Vite 項目可以使用官方插件 @vitejs/plugin-basic-ssl, 已經幫你生成好了證書,直接引入該插件即可。

// vite.config.js
import basicSsl from '@vitejs/plugin-basic-ssl'

export default {
  plugins: [
    basicSsl()
  ]
}
複製代碼

啓動服務後訪問 https://localhost:5173 即可。

1.4.3、自動打開瀏覽器

server.open

  • 類型: boolean | string

在開發服務器啓動時自動在瀏覽器中打開應用程序。當此值爲字符串時,會被用作 URL 的路徑名。若你想指定喜歡的瀏覽器打開服務器,你可以設置環境變量 process.env.BROWSER(例如:firefox)。查看 這個 open 包 獲取更多細節。

示例:

export default defineConfig({
  server: {
    open: '/docs/index.html'
  }
})

1.4.4、別名

resolve.alias

  • 類型:Record<string, string> | Array<{ find: string | RegExp, replacement: string, customResolver?: ResolverFunction | ResolverObject }>

將會被傳遞到 @rollup/plugin-alias 作爲 entries 的選項。也可以是一個對象,或一個 { find, replacement, customResolver } 的數組。

當使用文件系統路徑的別名時,請始終使用絕對路徑。相對路徑的別名值會原封不動地被使用,因此無法被正常解析。

更高級的自定義解析方法可以通過 插件 實現。

  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '/com':path.resolve(__dirname,'src/components')
    },
    extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']
  },

1.4.5、SCSS

css直接支持

sass無需配置vite,直接安裝即可直接使用

npm i sass -D

如果想全局引用可以做如下配置:

src/assets/scss/global.scss

$maincolor:#00f;

vite.config

  css:
  {
    preprocessorOptions:{
      scss:{
        additionalData:`@import "@/assets/scss/global.scss";`
      }
    }
  }

Counter.vue

<style lang="scss" scoped>
$bgcolor: #dfe;
.cls1 {
  background: $bgcolor;
  color: $maincolor;
}
</style>

運行

1.4.6、less

less無需配置vite,直接安裝即可直接使用

npm i less -D

如果想全局引用可以做如下配置:

src/assets/less/global.less

@mycolor:#f00;

vite.config

  css:
  {
    preprocessorOptions:{
      scss:{
        additionalData:`@import "@/assets/scss/global.scss";`
      },
      less:{
        additionalData:`@import "@/assets/less/global.less";`        
      }
    }
  } 

Counter.vue

<style lang="less" scoped>
@bgcolor: #fde;
.cls1 {
  background: @bgcolor;
  color: @mycolor;
}
</style>

運行:

1.4.7、設置最終構建的瀏覽器兼容目標

??與||的區別

//或運算如果爲0,null,undefined,false,""則取表達式2的值
let v=100;
let c=v||"默認值1";
console.log(c);
 
//??如果第1個表達式的值爲undefined,null則取表達式2的值,否則取表達式1的值,ES2020新增加
let vv=null;
let cc=vv??"默認值2";
let dd=vv===null||vv===undefined?"默認值2":vv;
console.log(cc);

let c=1;  //或運算如果爲0,null,undefined,false,""則取表達式2的值,否則取表達式1的值

let v=c||2;

console.log(v);

let e=null; //??如果第1個表達式的值爲undefined,null則取表達式2的值,否則取表達式1的值

let f=e??3;

console.log(f);

let g=c??4;

console.log(g);

都可以使用?:表達式替代

build.target

設置最終構建的瀏覽器兼容目標。默認值是一個 Vite 特有的值——'modules',這是指 支持原生 ES 模塊原生 ESM 動態導入 和 import.meta 的瀏覽器。

另一個特殊值是 “esnext” —— 即假設有原生動態導入支持,並且將會轉譯得儘可能小:

  • 如果 build.minify 選項爲 'terser''esnext' 將會強制降級爲 'es2019'
  • 其他情況下將完全不會執行轉譯。

轉換過程將會由 esbuild 執行,並且此值應該是一個合法的 esbuild 目標選項。自定義目標也可以是一個 ES 版本(例如:es2015)、一個瀏覽器版本(例如:chrome58)或是多個目標組成的一個數組。

注意:如果代碼包含不能被 esbuild 安全地編譯的特性,那麼構建將會失敗。查看 esbuild 文檔 獲取更多細節。

<template>
  <div class="cls1">
    <input v-model="_name" />
    {{ yourname }}
  </div>
</template>
<script lang="ts">
import { computed, ref } from "vue";

export default {
  setup() {
    let _name = ref("");
    let yourname = computed({
      get() {
        return _name.value;
      },
      set(value) {
        _name.value = value ?? "Hello ES2020!";
      },
    });
    return { yourname, _name };
  },
};
</script>
<style lang="less" scoped>
@bgcolor: #fde;
.cls1 {
  background: @bgcolor;
  color: @mycolor;
}
</style>

1.4.8、指定輸出路徑

build.outDir

  • 類型: string
  • 默認: dist

指定輸出路徑(相對於 項目根目錄).

1.4.9、靜態資源目錄

build.assetsDir

  • 類型: string
  • 默認: assets

指定生成靜態資源的存放路徑(相對於 build.outDir)。

1.4.10、內聯資源大小限定

build.assetsInlineLimit

  • 類型: number
  • 默認: 4096 (4kb)

小於此閾值的導入或引用資源將內聯爲 base64 編碼,以避免額外的 http 請求。設置爲 0 可以完全禁用此項。

Git LFS 佔位符會自動排除在內聯之外,因爲它們不包含它們所表示的文件的內容。

1.4.11、拆分CSS代碼

build.cssCodeSplit

  • 類型: boolean
  • 默認: true

啓用/禁用 CSS 代碼拆分。當啓用時,在異步 chunk 中導入的 CSS 將內聯到異步 chunk 本身,並在其被加載時插入。

如果禁用,整個項目中的所有 CSS 將被提取到一個 CSS 文件中。

1.4.12、壓縮空間

build.minify

  • 類型: boolean | 'terser' | 'esbuild'
  • 默認: 'esbuild'

設置爲 false 可以禁用最小化混淆,或是用來指定使用哪種混淆器。默認爲 Esbuild,它比 terser 快 20-40 倍,壓縮率只差 1%-2%。Benchmarks

注意,在 lib 模式下使用 'es' 時,build.minify 選項不會縮減空格,因爲會移除掉 pure 標註,導致破壞 tree-shaking。

當設置爲 'terser' 時必須先安裝 Terser。

npm add -D terser
選項 
--target <target> 編譯目標(默認爲:"modules")(string)
--outDir <dir> 輸出目錄(默認爲:dist)(string)
--assetsDir <dir> 在輸出目錄下放置資源的目錄(默認爲:"assets")(string)
--assetsInlineLimit <number> 靜態資源內聯爲 base64 編碼的閾值,以字節爲單位(默認爲:4096)(number)
--ssr [entry] 爲服務端渲染配置指定入口文件 (string)
--sourcemap 構建後輸出 source map 文件(默認爲:false)(boolean)
--minify [minifier] 允許或禁用最小化混淆,或指定使用哪種混淆器(默認爲:"esbuild")(boolean | "terser" | "esbuild")
--manifest [name] 構建後生成 manifest.json 文件 (boolean | string)
--ssrManifest [name] 構建後生成 SSR manifest.json 文件 (boolean | string)
--force 強制優化器忽略緩存並重新構建(實驗性)(boolean)
--emptyOutDir 若輸出目錄在根目錄外,強制清空輸出目錄 (boolean)
-w, --watch 在磁盤中模塊發生變化時,重新構建 (boolean)
-c, --config <file> 使用指定的配置文件 (string)
--base <path> 公共基礎路徑(默認爲:/)(string)
-l, --logLevel <level> Info | warn | error | silent (string)
--clearScreen 允許或禁用打印日誌時清除屏幕 (boolean)
-d, --debug [feat] 顯示調試日誌 (string | boolean)
-f, --filter <filter> 過濾調試日誌 (string)
-m, --mode <mode> 設置環境模式 (string)
-h, --help 顯示可用的 CLI 選項

1.4.13、預覽

你可以運行 npm run build 命令來執行應用的構建。

$ npm run build

默認情況下,構建會輸出到 dist 文件夾中。你可以部署這個 dist 文件夾到任何你喜歡的平臺。

本地測試應用

當你構建完成應用後,你可以通過運行 npm run preview 命令,在本地測試該應用。

$ npm run build
$ npm run preview

vite preview 命令會在本地啓動一個靜態 Web 服務器,將 dist 文件夾運行在 http://localhost:4173。這樣在本地環境下查看該構建產物是否正常可用就方便多了。

你可以通過 --port 參數來配置服務的運行端口。

{
  "scripts": {
    "preview": "vite preview --port 8080"
  }
}

現在 preview 命令會將服務器運行在 http://localhost:8080

選項 
--host [host] 指定主機名稱 (string)
--port <port> 指定端口 (number)
--strictPort 如果指定的端口已在使用中,則退出 (boolean)
--https 使用 TLS + HTTP/2 (boolean)
--open [path] 啓動時打開瀏覽器 (boolean | string)
--outDir <dir> 輸出目錄(默認爲:dist)(string)
-c, --config <file> 使用指定的配置文件 (string)
--base <path> 公共基礎路徑(默認爲:/)(string)
-l, --logLevel <level> Info | warn | error | silent (string)
--clearScreen 允許或禁用打印日誌時清除屏幕 (boolean)
-d, --debug [feat] 顯示調試日誌 (string | boolean)
-f, --filter <filter> 過濾調試日誌 (string)
-m, --mode <mode> 設置環境模式 (string)
-h, --help 顯示可用的 CLI 選項

preview.host

爲開發服務器指定 ip 地址。 設置爲 0.0.0.0 或 true 會監聽所有地址,包括局域網和公共地址。

還可以通過 CLI 進行設置,使用 --host 0.0.0.0 或 --host

注意

在某些情況下,可能響應的是其他服務器而不是 Vite。 查看 server.host 瞭解更多細節。

preview.port

  • 類型: number
  • 默認: 4173

指定開發服務器端口。注意,如果設置的端口已被使用,Vite 將自動嘗試下一個可用端口,所以這可能不是最終監聽的服務器端口。

示例:

export default defineConfig({
  server: {
    port: 3030
  },
  preview: {
    port: 8080
  }
})

preview.strictPort

設置爲 true 時,如果端口已被使用,則直接退出,而不會再進行後續端口的嘗試。

preview.https

  • 類型: boolean | https.ServerOptions
  • 默認: server.https

啓用 TLS + HTTP/2。注意,只有在與 server.proxy 選項 同時使用時,纔會降級爲 TLS。

該值也可以傳遞給 https.createServer() 的 options 對象

preview.open

開發服務器啓動時,自動在瀏覽器中打開應用程序。當該值爲字符串時,它將被用作 URL 的路徑名。如果你想在你喜歡的某個瀏覽器打開該開發服務器,你可以設置環境變量 process.env.BROWSER (例如 firefox)。欲瞭解更多細節,請參閱 open 包的源碼

preview.proxy

  • 類型: Record<string, string | ProxyOptions>
  • 默認: server.proxy

爲開發服務器配置自定義代理規則。其值的結構爲 { key: options } 的對象。如果 key 以 ^ 開頭,它將被識別爲 RegExp,其中 configure 選項可用於訪問代理實例。

基於 http-proxy 實現,完整的參數列表參見 此鏈接

preview.cors

  • 類型: boolean | CorsOptions
  • 默認: server.cors

爲開發服務器配置 CORS。此功能默認啓用並支持任何來源。可傳遞一個 options 對象 來進行配置,或者傳遞 false 來禁用此行爲。

1.4.14、使用插件

Vite 可以使用插件進行擴展,這得益於 Rollup 優秀的插件接口設計和一部分 Vite 獨有的額外選項。這意味着 Vite 用戶可以利用 Rollup 插件的強大生態系統,同時根據需要也能夠擴展開發服務器和 SSR 功能。

添加一個插件

若要使用一個插件,需要將它添加到項目的 devDependencies 並在 vite.config.js 配置文件中的 plugins 數組中引入它。例如,要想爲傳統瀏覽器提供支持,可以按下面這樣使用官方插件 @vitejs/plugin-legacy

$ npm add -D @vitejs/plugin-legacy
// vite.config.js
import legacy from '@vitejs/plugin-legacy'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11'],
    }),
  ],
})

plugins 也可以接受包含多個插件作爲單個元素的預設。這對於使用多個插件實現的複雜特性(如框架集成)很有用。該數組將在內部被扁平化。

Falsy 虛值的插件將被忽略,可以用來輕鬆地啓用或停用插件。

什麼是polyfill

簡單來說,polyfill就是兼容舊瀏覽器的代碼塊,磨平差異。比如說 有的瀏覽器不支持 globalThis, 那我們可以自己實現一個globalThis然後注入到script中

注意:polyfill代碼編譯(renderLegacyChunks)是兩個概念, 前者是添加額外的代碼來使得舊瀏覽器支持某些特性,後者是把瀏覽器不認識的語法轉化爲可以運行的語法

vite的polyfill分爲 modern polyfill(modernPolyfills屬性)和 legacy polyfill(polyfills屬性),之所以區分開來,是爲了儘量減少polyfills的大小

targets

設置目標瀏覽器兼容的範圍。

  • 類型:string|string[]|{[key: string]: string}
  • 默認值:defaults

如果顯式設置,則將其傳遞給@babel/preset-env。該選項與Browserslist 兼容。默認值:defaults,是 Browserslist 推薦的值。

 

Browserslist 在不同前端工具之間共享目標瀏覽器和 Node.js 版本的配置(不區分大小寫)。
defaults Browserslist 的默認瀏覽器(> 0.5%,last 2 versions,Firefox ESR,not dead)。
dead 沒有官方支持或更新的瀏覽器 24 個月。現在它是IE 11, IE_Mob 11, BlackBerry 10, BlackBerry 7, Samsung 4 和 OperaMobile 12.1,所有版本的 Baidu 瀏覽器。
not ie <= 8 從以前的查詢中排除 IE 8 及更低版本。
按使用統計
最新版本
  • last 2 versions:每個瀏覽器的最後 2 個版本。
  • last 2 Chrome versions: Chrome 瀏覽器的最後 2 個版本。
  • last 2 major versions或last 2 iOS major versions:最近 2 個主要版本的所有次要/補丁版本。
瀏覽器版本
  • iOS 7:直接iOS瀏覽器版本7。
  • Firefox > 20: Firefox 20 之後的版本。還可以使用>=<<=。它也適用於 Node.js。
  • ie 6-8:選擇包含範圍的版本。
  • Firefox ESR:最新的 Firefox 擴展支持版本。
  • PhantomJS 2.1和PhantomJS 1.9:選擇類似於 PhantomJS 運行時的 Safari 版本。
Node.js 版本
  • node 10and node 10.4:選擇最新的 Node.js10.x.x 或10.4.x發佈。
  • last 2 node versions:選擇 2 個最新的 Node.js 版本。
  • last 2 node major versions:選擇 2 個最新的主要版本 Node.js 版本。
  • current node: Browserslist 現在使用的 Node.js 版本。
  • maintained node versions:所有 Node.js 版本,仍然由 Node.js 基金會維護。
extends browserslist-config-mycompany 從 browserslist-config-mycompanynpm 包中獲取查詢。
supports es6-module 支持特定功能的瀏覽器。es6-module 這是 Can I Use 頁面 feat 的 URL 中的參數。可以在 caniuse-lite/data/features 找到所有可用功能的列表。
browserslist config Browserslist 配置中定義的瀏覽器。在差異服務中很有用,可以修改用戶的配置,例如 browserslist config and supports es6-module.
since 2015or last 2 years 自 2015 年以來發布的所有版本(也since 2015-03和since 2015-03-10)。
unreleased versions或unreleased Chrome versions alpha 和 beta 版本。

 

在項目根目錄中,查詢選擇了哪些瀏覽器。

npx browserslist

查找插件

Vite 旨在爲常見的 Web 開發範式提供開箱即用的支持。在尋找一個 Vite 或兼容的 Rollup 插件之前,請先查看 功能指引。大量在 Rollup 項目中需要使用插件的用例在 Vite 中已經覆蓋到了。

查看 Plugins 章節 獲取官方插件信息。社區插件列表請參見 awesome-vite。而對於兼容的 Rollup 插件,請查看 Vite Rollup 插件 獲取一個帶使用說明的兼容 Rollup 官方插件列表,若列表中沒有找到,則請參閱 Rollup 插件兼容性章節

你也可以使用此 npm Vite 插件搜索鏈接 來找到一些遵循了 推薦約定 的 Vite 插件,或者通過 npm Rollup 插件搜索鏈接 獲取 Rollup 插件。

vite-plugin-html

https://github.com/vbenjs/vite-plugin-html/blob/main/README.zh_CN.md

功能

  • HTML 壓縮能力
  • EJS 模版能力
  • 多頁應用支持
  • 支持自定義entry
  • 支持自定義template

安裝 (yarn or npm)

node version: >=12.0.0

vite version: >=2.0.0

yarn add vite-plugin-html -D

npm i vite-plugin-html -D

使用

  • 在 index.html 中增加 EJS 標籤,例如
<head>
  <meta charset="UTF-8" />
  <link rel="icon" href="/favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title><%- title %></title>
  <%- injectScript %>
</head>
  • 在 vite.config.ts 中配置,該方式可以按需引入需要的功能即可
import { defineConfig, Plugin } from 'vite'
import vue from '@vitejs/plugin-vue'

import { createHtmlPlugin } from 'vite-plugin-html'

export default defineConfig({
  plugins: [
    vue(),
    createHtmlPlugin({
      minify: true,
      /**
       * 在這裏寫entry後,你將不需要在`index.html`內添加 script 標籤,原有標籤需要刪除
       * @default src/main.ts
       */
      entry: 'src/main.ts',
      /**
       * 如果你想將 `index.html`存放在指定文件夾,可以修改它,否則不需要配置
       * @default index.html
       */
      template: 'public/index.html',

      /**
       * 需要注入 index.html ejs 模版的數據
       */
      inject: {
        data: {
          title: 'index',
          injectScript: `<script src="./inject.js"></script>`,
        },
        tags: [
          {
            injectTo: 'body-prepend',
            tag: 'div',
            attrs: {
              id: 'tag',
            },
          },
        ],
      },
    }),
  ],
})

多頁應用配置

import { defineConfig } from 'vite'
import { createHtmlPlugin } from 'vite-plugin-html'

export default defineConfig({
  plugins: [
    createHtmlPlugin({
      minify: true,
      pages: [
        {
          entry: 'src/main.ts',
          filename: 'index.html',
          template: 'public/index.html',
          injectOptions: {
            data: {
              title: 'index',
              injectScript: `<script src="./inject.js"></script>`,
            },
            tags: [
              {
                injectTo: 'body-prepend',
                tag: 'div',
                attrs: {
                  id: 'tag1',
                },
              },
            ],
          },
        },
        {
          entry: 'src/other-main.ts',
          filename: 'other.html',
          template: 'public/other.html',
          injectOptions: {
            data: {
              title: 'other page',
              injectScript: `<script src="./inject.js"></script>`,
            },
            tags: [
              {
                injectTo: 'body-prepend',
                tag: 'div',
                attrs: {
                  id: 'tag2',
                },
              },
            ],
          },
        },
      ],
    }),
  ],
})

參數說明

createHtmlPlugin(options: UserOptions)

UserOptions

參數類型默認值說明
entry string src/main.ts 入口文件
template string index.html 模板的相對路徑
inject InjectOptions - 注入 HTML 的數據
minify boolean|MinifyOptions - 是否壓縮 html
pages PageOption - 多頁配置

InjectOptions

參數類型默認值說明
data Record<string, any> - 注入的數據
ejsOptions EJSOptions - ejs 配置項EJSOptions
tags HtmlTagDescriptor - 需要注入的標籤列表

data 可以在 html 中使用 ejs 模版語法獲取

env 注入

默認會向 index.html 注入 .env 文件的內容,類似 vite 的 loadEnv函數

PageOption

參數類型默認值說明
filename string - html 文件名
template string index.html 模板的相對路徑
entry string src/main.ts 入口文件
injectOptions InjectOptions - 注入 HTML 的數據

MinifyOptions

默認壓縮配置

    collapseWhitespace: true,
    keepClosingSlash: true,
    removeComments: true,
    removeRedundantAttributes: true,
    removeScriptTypeAttributes: true,
    removeStyleLinkTypeAttributes: true,
    useShortDoctype: true,
    minifyCSS: true,

運行示例

pnpm install

# spa
cd ./packages/playground/basic

pnpm run dev

# map
cd ./packages/playground/mpa

pnpm run dev

1.4.15、CSS Modules

任何以 .module.css 爲後綴名的 CSS 文件都被認爲是一個 CSS modules 文件。導入這樣的文件會返回一個相應的模塊對象:

/* example.module.css */
.red {
  color: red;
}
import classes from './example.module.css'
document.getElementById('foo').className = classes.red

CSS modules 行爲可以通過 css.modules 選項 進行配置。

如果 css.modules.localsConvention 設置開啓了 camelCase 格式變量名轉換(例如 localsConvention: 'camelCaseOnly'),你還可以使用按名導入。

// .apply-color -> applyColor
import { applyColor } from './example.module.css'
document.getElementById('foo').className = applyColor

<template>
  <div>
    <h2 id="title">Home - 首頁</h2>
    <button @click="setcolor">設置文字爲紅色</button>
  </div>
</template>
<script lang="ts" setup>
import mycss from "../assets/css/home.module.css";

function setcolor() {
  document.getElementById("title")!.className = mycss.red;
}
</script>
<style scoped></style>

home.module.css

.red{
    color:red;
}

.font-color{
    color:blue;
    background: #def;
}

1.4.16、禁用 CSS 注入頁面

自動注入 CSS 內容的行爲可以通過 ?inline 參數來關閉。在關閉時,被處理過的 CSS 字符串將會作爲該模塊的默認導出,但樣式並沒有被注入到頁面中。

import './foo.css' // 樣式將會注入頁面
import otherStyles from './bar.css?inline' // 樣式不會注入頁面

1.4.17、靜態資源處理

導入一個靜態資源會返回解析後的 URL:

import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

添加一些特殊的查詢參數可以更改資源被引入的方式:

// 顯式加載資源爲一個 URL
import assetAsURL from './asset.js?url'
// 以字符串形式加載資源
import assetAsString from './shader.glsl?raw'
// 加載爲 Web Worker
import Worker from './worker.js?worker'
// 在構建時 Web Worker 內聯爲 base64 字符串
import InlineWorker from './worker.js?worker&inline'

二、ESLint

2.1、概要

eslint 屬於一種 QA(Quality Assurance)工具,是一個 ECMAScript/JavaScript 語法規則和代碼風格的檢查工具,可以用來保證寫出語法正確、風格統一的代碼。

eslint 完全可配置,它的目標是提供一個插件化的 javascript 代碼檢測工具。這意味着您可以關閉每個規則,只能使用基本語法驗證,或者混合並匹配捆綁的規則和自定義規則,使 eslint 完美的適用於當前項目。

目標:能夠知道 ESLint 常見的 語法規則 ,並在實際開發中遵守這些規則

官方概念:ESLint 是可組裝的 JavaScript 和 JSX 檢查工具。

通俗理解:一個代碼 格式 的檢查 工具 ,用來 約束 團隊成員的 代碼風格 。

好處 :

保證團隊協作開發時,編寫出來的 代碼風格 保持一致。例如:

① 函數名和括號之間要有一個空格
② JS 中的字符串,統一使用 單引號 表示
③ 一行代碼結束加不加 分號
④ 不允許 出現 ≥2 個 的連續空行
⑤ import 必須放到文件的最上面
⑥ 文件結尾要 留一行空行
⑦ 對象的末尾不要有多餘的 逗號

官網:https://zh-hans.eslint.org/

源碼:https://github.com/eslint/eslint

[ESLint 中文官方網站]:

前提條件:內置 SSL 支持的 Node.js 版本(^12.22.0^14.17.0 或 >=16.0.0),如果你使用的是官方 Node.js 發行版,那麼已經內置了 SSL 支持。

你可以使用該命令安裝並配置 ESLint:

npm init @eslint/config

注意:使用 npm init @eslint/config 時,運行目錄需要已經有 package.json 文件了。如果還沒有該文件,請確保在此之前運行 npm init 或 yarn init

在此之後,你可以像這樣使用 ESLint 檢查任一文件或目錄:

npx eslint yourfile.js

# 或

yarn run eslint yourfile.js

也可以全局安裝 ESLint 而不僅限於本地(使用 npm install eslint --global)。但並不推薦這樣做,因爲無論使用哪種安裝方式,你都需要在本地安裝插件和可共享配置。

1、創建一個空項目、初始化爲node項目

 2、配置ESLint項目

 3、創建index.js文件

for(var i=0;i<100;i--){}

注意這裏故意把i++寫成了i--,代碼塊中沒有內容。

4、執行eslint檢查

發現了2個錯誤

2.3、常見錯誤與問題

ESLint完整規則(rules)地址:https://eslint.org/docs/rules/

 規則解釋一:

"no-alert": 0,//禁止使用alert confirm prompt
"no-array-constructor": 2,//禁止使用數組構造器
"no-bitwise": 0,//禁止使用按位運算符
"no-caller": 1,//禁止使用arguments.caller或arguments.callee
"no-catch-shadow": 2,//禁止catch子句參數與外部作用域變量同名
"no-class-assign": 2,//禁止給類賦值
"no-cond-assign": 2,//禁止在條件表達式中使用賦值語句
"no-console": 2,//禁止使用console
"no-const-assign": 2,//禁止修改const聲明的變量
"no-constant-condition": 2,//禁止在條件中使用常量表達式 if(true) if(1)
"no-continue": 0,//禁止使用continue
"no-control-regex": 2,//禁止在正則表達式中使用控制字符
"no-debugger": 2,//禁止使用debugger
"no-delete-var": 2,//不能對var聲明的變量使用delete操作符
"no-div-regex": 1,//不能使用看起來像除法的正則表達式/=foo/
"no-dupe-keys": 2,//在創建對象字面量時不允許鍵重複 {a:1,a:1}
"no-dupe-args": 2,//函數參數不能重複
"no-duplicate-case": 2,//switch中的case標籤不能重複
"no-else-return": 2,//如果if語句裏面有return,後面不能跟else語句
"no-empty": 2,//塊語句中的內容不能爲空
"no-empty-character-class": 2,//正則表達式中的[]內容不能爲空
"no-empty-label": 2,//禁止使用空label
"no-eq-null": 2,//禁止對null使用==或!=運算符
"no-eval": 1,//禁止使用eval
"no-ex-assign": 2,//禁止給catch語句中的異常參數賦值
"no-extend-native": 2,//禁止擴展native對象
"no-extra-bind": 2,//禁止不必要的函數綁定
"no-extra-boolean-cast": 2,//禁止不必要的bool轉換
"no-extra-parens": 2,//禁止非必要的括號
"no-extra-semi": 2,//禁止多餘的冒號
"no-fallthrough": 1,//禁止switch穿透
"no-floating-decimal": 2,//禁止省略浮點數中的0 .5 3.
"no-func-assign": 2,//禁止重複的函數聲明
"no-implicit-coercion": 1,//禁止隱式轉換
"no-implied-eval": 2,//禁止使用隱式eval
"no-inline-comments": 0,//禁止行內備註
"no-inner-declarations": [2, "functions"],//禁止在塊語句中使用聲明(變量或函數)
"no-invalid-regexp": 2,//禁止無效的正則表達式
"no-invalid-this": 2,//禁止無效的this,只能用在構造器,類,對象字面量
"no-irregular-whitespace": 2,//不能有不規則的空格
"no-iterator": 2,//禁止使用__iterator__ 屬性
"no-label-var": 2,//label名不能與var聲明的變量名相同
"no-labels": 2,//禁止標籤聲明
"no-lone-blocks": 2,//禁止不必要的嵌套塊
"no-lonely-if": 2,//禁止else語句內只有if語句
"no-loop-func": 1,//禁止在循環中使用函數(如果沒有引用外部變量不形成閉包就可以)
"no-mixed-requires": [0, false],//聲明時不能混用聲明類型
"no-mixed-spaces-and-tabs": [2, false],//禁止混用tab和空格
"linebreak-style": [0, "windows"],//換行風格
"no-multi-spaces": 1,//不能用多餘的空格
"no-multi-str": 2,//字符串不能用\換行
"no-multiple-empty-lines": [1, {"max": 2}],//空行最多不能超過2行
"no-native-reassign": 2,//不能重寫native對象
"no-negated-in-lhs": 2,//in 操作符的左邊不能有!
"no-nested-ternary": 0,//禁止使用嵌套的三目運算
"no-new": 1,//禁止在使用new構造一個實例後不賦值
"no-new-func": 1,//禁止使用new Function
"no-new-object": 2,//禁止使用new Object()
"no-new-require": 2,//禁止使用new require
"no-new-wrappers": 2,//禁止使用new創建包裝實例,new String new Boolean new Number
"no-obj-calls": 2,//不能調用內置的全局對象,比如Math() JSON()
"no-octal": 2,//禁止使用八進制數字
"no-octal-escape": 2,//禁止使用八進制轉義序列
"no-param-reassign": 2,//禁止給參數重新賦值
"no-path-concat": 0,//node中不能使用__dirname或__filename做路徑拼接
"no-plusplus": 0,//禁止使用++,--
"no-process-env": 0,//禁止使用process.env
"no-process-exit": 0,//禁止使用process.exit()
"no-proto": 2,//禁止使用__proto__屬性
"no-redeclare": 2,//禁止重複聲明變量
"no-regex-spaces": 2,//禁止在正則表達式字面量中使用多個空格 /foo bar/
"no-restricted-modules": 0,//如果禁用了指定模塊,使用就會報錯
"no-return-assign": 1,//return 語句中不能有賦值表達式
"no-script-url": 0,//禁止使用javascript:void(0)
"no-self-compare": 2,//不能比較自身
"no-sequences": 0,//禁止使用逗號運算符
"no-shadow": 2,//外部作用域中的變量不能與它所包含的作用域中的變量或參數同名
"no-shadow-restricted-names": 2,//嚴格模式中規定的限制標識符不能作爲聲明時的變量名使用
"no-spaced-func": 2,//函數調用時 函數名與()之間不能有空格
"no-sparse-arrays": 2,//禁止稀疏數組, [1,,2]
"no-sync": 0,//nodejs 禁止同步方法
"no-ternary": 0,//禁止使用三目運算符
"no-trailing-spaces": 1,//一行結束後面不要有空格
"no-this-before-super": 0,//在調用super()之前不能使用this或super
"no-throw-literal": 2,//禁止拋出字面量錯誤 throw "error";
"no-undef": 1,//不能有未定義的變量
"no-undef-init": 2,//變量初始化時不能直接給它賦值爲undefined
"no-undefined": 2,//不能使用undefined
"no-unexpected-multiline": 2,//避免多行表達式
"no-underscore-dangle": 1,//標識符不能以_開頭或結尾
"no-unneeded-ternary": 2,//禁止不必要的嵌套 var isYes = answer === 1 ? true : false;
"no-unreachable": 2,//不能有無法執行的代碼
"no-unused-expressions": 2,//禁止無用的表達式
"no-unused-vars": [2, {"vars": "all", "args": "after-used"}],//不能有聲明後未被使用的變量或參數
"no-use-before-define": 2,//未定義前不能使用
"no-useless-call": 2,//禁止不必要的call和apply
"no-void": 2,//禁用void操作符
"no-var": 0,//禁用var,用let和const代替
"no-warning-comments": [1, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],//不能有警告備註
"no-with": 2,//禁用with

"array-bracket-spacing": [2, "never"],//是否允許非空數組裏面有多餘的空格
"arrow-parens": 0,//箭頭函數用小括號括起來
"arrow-spacing": 0,//=>的前/後括號
"accessor-pairs": 0,//在對象中使用getter/setter
"block-scoped-var": 0,//塊語句中使用var
"brace-style": [1, "1tbs"],//大括號風格
"callback-return": 1,//避免多次調用回調什麼的
"camelcase": 2,//強制駝峯法命名
"comma-dangle": [2, "never"],//對象字面量項尾不能有逗號
"comma-spacing": 0,//逗號前後的空格
"comma-style": [2, "last"],//逗號風格,換行時在行首還是行尾
"complexity": [0, 11],//循環複雜度
"computed-property-spacing": [0, "never"],//是否允許計算後的鍵名什麼的
"consistent-return": 0,//return 後面是否允許省略
"consistent-this": [2, "that"],//this別名
"constructor-super": 0,//非派生類不能調用super,派生類必須調用super
"curly": [2, "all"],//必須使用 if(){} 中的{}
"default-case": 2,//switch語句最後必須有default
"dot-location": 0,//對象訪問符的位置,換行的時候在行首還是行尾
"dot-notation": [0, { "allowKeywords": true }],//避免不必要的方括號
"eol-last": 0,//文件以單一的換行符結束
"eqeqeq": 2,//必須使用全等
"func-names": 0,//函數表達式必須有名字
"func-style": [0, "declaration"],//函數風格,規定只能使用函數聲明/函數表達式
"generator-star-spacing": 0,//生成器函數*的前後空格
"guard-for-in": 0,//for in循環要用if語句過濾
"handle-callback-err": 0,//nodejs 處理錯誤
"id-length": 0,//變量名長度
"indent": [2, 4],//縮進風格
"init-declarations": 0,//聲明時必須賦初值
"key-spacing": [0, { "beforeColon": false, "afterColon": true }],//對象字面量中冒號的前後空格
"lines-around-comment": 0,//行前/行後備注
"max-depth": [0, 4],//嵌套塊深度
"max-len": [0, 80, 4],//字符串最大長度
"max-nested-callbacks": [0, 2],//回調嵌套深度
"max-params": [0, 3],//函數最多隻能有3個參數
"max-statements": [0, 10],//函數內最多有幾個聲明
"new-cap": 2,//函數名首行大寫必須使用new方式調用,首行小寫必須用不帶new方式調用
"new-parens": 2,//new時必須加小括號
"newline-after-var": 2,//變量聲明後是否需要空一行
"object-curly-spacing": [0, "never"],//大括號內是否允許不必要的空格
"object-shorthand": 0,//強制對象字面量縮寫語法
"one-var": 1,//連續聲明
"operator-assignment": [0, "always"],//賦值運算符 += -=什麼的
"operator-linebreak": [2, "after"],//換行時運算符在行尾還是行首
"padded-blocks": 0,//塊語句內行首行尾是否要空行
"prefer-const": 0,//首選const
"prefer-spread": 0,//首選展開運算
"prefer-reflect": 0,//首選Reflect的方法
"quotes": [1, "single"],//引號類型 `` "" ''
"quote-props":[2, "always"],//對象字面量中的屬性名是否強制雙引號
"radix": 2,//parseInt必須指定第二個參數
"id-match": 0,//命名檢測
"require-yield": 0,//生成器函數必須有yield
"semi": [2, "always"],//語句強制分號結尾
"semi-spacing": [0, {"before": false, "after": true}],//分號前後空格
"sort-vars": 0,//變量聲明時排序
"space-after-keywords": [0, "always"],//關鍵字後面是否要空一格
"space-before-blocks": [0, "always"],//不以新行開始的塊{前面要不要有空格
"space-before-function-paren": [0, "always"],//函數定義時括號前面要不要有空格
"space-in-parens": [0, "never"],//小括號裏面要不要有空格
"space-infix-ops": 0,//中綴操作符周圍要不要有空格
"space-return-throw-case": 2,//return throw case後面要不要加空格
"space-unary-ops": [0, { "words": true, "nonwords": false }],//一元運算符的前/後要不要加空格
"spaced-comment": 0,//註釋風格要不要有空格什麼的
"strict": 2,//使用嚴格模式
"use-isnan": 2,//禁止比較時使用NaN,只能用isNaN()
"valid-jsdoc": 0,//jsdoc規則
"valid-typeof": 2,//必須使用合法的typeof的值
"vars-on-top": 2,//var必須放在作用域頂部
"wrap-iife": [2, "inside"],//立即執行函數表達式的小括號風格
"wrap-regex": 0,//正則表達式字面量用小括號包起來
"yoda": [2, "never"]//禁止尤達條件
View Code

規則解釋二:

{
        /**
         * 禁止 for 循環出現方向錯誤的循環,比如 for (i = 0; i < 10; i--)
         * @category Possible Errors
         */
        'for-direction': 'error',


        /**
         * getter 必須有返回值,並且禁止返回空,比如 return;
         * @category Possible Errors
         */
        'getter-return': [
            'error',
            {
                allowImplicit: false
            }
        ],


        /**
         * 禁止將 async 函數做爲 new Promise 的回調函數
         * @category Possible Errors
         * @reason 出現這種情況時,一般不需要使用 new Promise 實現異步了
         */
        'no-async-promise-executor': 'error',


        /**
         * 禁止將 await 寫在循環裏,因爲這樣就無法同時發送多個異步請求了
         * @category Possible Errors
         * @reason 要求太嚴格了,有時需要在循環中寫 await
         */
        'no-await-in-loop': 'off',


        /**
         * 禁止與負零進行比較
         * @category Possible Errors
         */
        'no-compare-neg-zero': 'error',


        /**
         * 禁止在判斷表達式中使用賦值語句,除非這個賦值語句被括號包起來了
         * @category Possible Errors
         */
        'no-cond-assign': ['error', 'except-parens'],


        /**
         * 禁止使用 console
         * @category Possible Errors
         * @reason console 的使用很常見
         */
        'no-console': 'off',


        /**
         * 禁止將常量作爲分支條件判斷中的判斷表達式,但允許作爲循環條件判斷中的測試表達式
         * @category Possible Errors
         */
        'no-constant-condition': [
            'error',
            {
                checkLoops: false
            }
        ],


        /**
         * 禁止在正則表達式中出現 Ctrl 鍵的 ASCII 表示,即禁止使用 /\x1f/
         * @category Possible Errors
         * @reason 幾乎不會遇到這種場景
         */
        'no-control-regex': 'error',


        /**
         * 禁止使用 debugger
         * @category Possible Errors
         */
        'no-debugger': 'error',


        /**
         * 禁止在函數參數中出現重複名稱的參數
         * @category Possible Errors
         */
        'no-dupe-args': 'error',


        /**
         * 禁止在對象字面量中出現重複名稱的鍵名
         * @category Possible Errors
         */
        'no-dupe-keys': 'error',


        /**
         * 禁止在 switch 語句中出現重複測試表達式的 case
         * @category Possible Errors
         */
        'no-duplicate-case': 'error',


        /**
         * 禁止出現空代碼塊,允許 catch 爲空代碼塊
         * @category Possible Errors
         */
        'no-empty': [
            'error',
            {
                allowEmptyCatch: true
            }
        ],


        /**
         * 禁止在正則表達式中使用空的字符集 []
         * @category Possible Errors
         */
        'no-empty-character-class': 'error',


        /**
         * 禁止將 catch 的第一個參數 error 重新賦值
         * @category Possible Errors
         */
        'no-ex-assign': 'error',


        /**
         * 禁止不必要的布爾類型轉換,比如 !! 或 Boolean
         * @category Possible Errors
         * @fixable
         */
        'no-extra-boolean-cast': 'error',


        /**
         * 禁止函數表達式中出現多餘的括號
         * @category Possible Errors
         * @fixable
         */
        'no-extra-parens': ['error', 'functions'],


        /**
         * 禁止出現多餘的分號
         * @category Possible Errors
         * @fixable
         */
        'no-extra-semi': 'error',


        /**
         * 禁止將一個函數聲明重新賦值,如:
         * @category Possible Errors
         */
        'no-func-assign': 'error',


        /**
         * 禁止在 if 代碼塊內出現函數聲明
         * @category Possible Errors
         */
        'no-inner-declarations': ['error', 'both'],


        /**
         * 禁止在 RegExp 構造函數中出現非法的正則表達式
         * @category Possible Errors
         */
        'no-invalid-regexp': 'error',


        /**
         * 禁止使用特殊空白符(比如全角空格),除非是出現在字符串、正則表達式或模版字符串中
         * @category Possible Errors
         */
        'no-irregular-whitespace': [
            'error',
            {
                skipStrings: true,
                skipComments: false,
                skipRegExps: true,
                skipTemplates: true
            }
        ],


        /**
         * 禁止正則表達式中使用肉眼無法區分的特殊字符
         * @category Possible Errors
         * @reason 某些特殊字符很難看出差異,最好不要在正則中使用
         */
        'no-misleading-character-class': 'error',


        /**
         * 禁止將 Math, JSON 或 Reflect 直接作爲函數調用
         * @category Possible Errors
         */
        'no-obj-calls': 'error',


        /**
         * 禁止使用 hasOwnProperty, isPrototypeOf 或 propertyIsEnumerable
         * @category Possible Errors
         * @reason hasOwnProperty 比較常用
         */
        'no-prototype-builtins': 'off',


        /**
         * 禁止在正則表達式中出現連續的空格,必須使用 /foo {3}bar/ 代替
         * @category Possible Errors
         * @fixable
         */
        'no-regex-spaces': 'error',


        /**
         * 禁止在數組中出現連續的逗號,如 let foo = [,,]
         * @category Possible Errors
         */
        'no-sparse-arrays': 'error',


        /**
         * 禁止在普通字符串中出現模版字符串裏的變量形式,如 'Hello ${name}!'
         * @category Possible Errors
         */
        'no-template-curly-in-string': 'error',


        /**
         * 禁止出現難以理解的多行表達式
         * @category Possible Errors
         */
        'no-unexpected-multiline': 'error',


        /**
         * 禁止在 return, throw, break 或 continue 之後還有代碼
         * @category Possible Errors
         */
        'no-unreachable': 'error',


        /**
         * 禁止在 finally 中出現 return, throw, break 或 continue
         * @category Possible Errors
         */
        'no-unsafe-finally': 'error',


        /**
         * 禁止在 in 或 instanceof 操作符的左側使用感嘆號,如 if (!key in object)
         * @category Possible Errors
         * @fixable
         */
        'no-unsafe-negation': 'error',


        /**
         * 禁止將 await 或 yield 的結果做爲運算符的後面項
         * @category Possible Errors
         * @reason 這樣會導致不符合預期的結果
         */
        'require-atomic-updates': 'error',


        /**
         * 必須使用 isNaN(foo) 而不是 foo === NaN
         * @category Possible Errors
         */
        'use-isnan': 'error',


        /**
         * typeof 表達式比較的對象必須是 'undefined', 'object', 'boolean', 'number', 'string', 'function' 或 'symbol'
         * @category Possible Errors
         */
        'valid-typeof': 'error',

        //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        /**
         * setter 必須有對應的 getter,getter 可以沒有對應的 setter
         * @category Best Practices
         */
        'accessor-pairs': [
            'error',
            {
                setWithoutGet: true,
                getWithoutSet: false
            }
        ],


        /**
         * 數組的方法除了 forEach 之外,回調函數必須有返回值
         * @category Best Practices
         */
        'array-callback-return': 'off',


        /**
         * 將 var 定義的變量視爲塊作用域,禁止在塊外使用
         * @category Best Practices
         */
        'block-scoped-var': 'error',


        /**
         * 在類的非靜態方法中,必須存在對 this 的引用
         * @category Best Practices
         * @reason 太嚴格了
         */
        'class-methods-use-this': 'error',


        /**
         * 禁止函數的循環複雜度超過 20,https://en.wikipedia.org/wiki/Cyclomatic_complexity
         * @category Best Practices
         */
        complexity: [
            'error',
            {
                max: 20
            }
        ],


        /**
         * 禁止函數在不同分支返回不同類型的值
         * @category Best Practices
         * @reason 太嚴格了
         */
        'consistent-return': 'off',


        /**
         * if 後面必須要有 {,除非是單行 if
         * @category Best Practices
         * @fixable
         */
        curly: ['error', 'multi-line', 'consistent'],


        /**
         * switch 語句必須有 default
         * @category Best Practices
         * @reason 太嚴格了
         */
        'default-case': 'off',


        /**
         * 鏈式調用的時候,點號必須放在第二行開頭處,禁止放在第一行結尾處
         * @category Best Practices
         * @fixable
         */
        'dot-location': ['error', 'property'],


        /**
         * 禁止出現 foo['bar'],必須寫成 foo.bar
         * @category Best Practices
         * @reason 當需要寫一系列屬性的時候,可以更統一
         * @fixable
         */
        'dot-notation': 'off',


        /**
         * 必須使用 === 或 !==,禁止使用 == 或 !=,與 null 比較時除外
         * @category Best Practices
         * @fixable
         */
        eqeqeq: [
            'error',
            'always',
            {
                null: 'ignore'
            }
        ],


        /**
         * for in 內部必須有 hasOwnProperty
         * @category Best Practices
         */
        'guard-for-in': 'error',


        /**
         * 限制一個文件中類的數量
         * @category Best Practices
         */
        'max-classes-per-file': 'off',


        /**
         * 禁止使用 alert
         * @category Best Practices
         * @reason alert 很常用
         */
        'no-alert': 'off',


        /**
         * 禁止使用 caller 或 callee
         * @category Best Practices
         */
        'no-caller': 'error',


        /**
         * switch 的 case 內有變量定義的時候,必須使用大括號將 case 內變成一個代碼塊
         * @category Best Practices
         */
        'no-case-declarations': 'error',


        /**
         * 禁止在正則表達式中出現形似除法操作符的開頭,如 let a = /=foo/
         * @category Best Practices
         * @reason 有代碼高亮的話,在閱讀這種代碼時,也完全不會產生歧義或理解上的困難
         */
        'no-div-regex': 'off',


        /**
         * 禁止在 else 內使用 return,必須改爲提前結束
         * @category Best Practices
         * @reason else 中使用 return 可以使代碼結構更清晰
         * @fixable
         */
        'no-else-return': 'off',


        /**
         * 不允許有空函數,除非是將一個空函數設置爲某個項的默認值
         * @category Best Practices
         */
        'no-empty-function': [
            'error',
            {
                allow: ['functions', 'arrowFunctions']
            }
        ],


        /**
         * 禁止解構中出現空 {} 或 []
         * @category Best Practices
         */
        'no-empty-pattern': 'error',


        /**
         * 禁止使用 foo == null,必須使用 foo === null
         * @category Best Practices
         * @reason foo == null 比較常用,可以用於判斷 foo 不是 undefined 並且不是 null,故允許此寫法
         */
        'no-eq-null': 'off',


        /**
         * 禁止使用 eval
         * @category Best Practices
         */
        'no-eval': 'error',


        /**
         * 禁止修改原生對象
         * @category Best Practices
         */
        'no-extend-native': 'error',


        /**
         * 禁止出現沒必要的 bind
         * @category Best Practices
         * @fixable
         */
        'no-extra-bind': 'error',


        /**
         * 禁止出現沒必要的 label
         * @category Best Practices
         * @fixable
         */
        'no-extra-label': 'error',


        /**
         * switch 的 case 內必須有 break, return 或 throw
         * @category Best Practices
         */
        'no-fallthrough': 'error',


        /**
         * 表示小數時,禁止省略 0,比如 .5
         * @category Best Practices
         * @fixable
         */
        'no-floating-decimal': 'error',


        /**
         * 禁止對全局變量賦值
         * @category Best Practices
         */
        'no-global-assign': 'error',


        /**
         * 禁止使用 !! ~ 等難以理解的運算符,僅允許使用 !!
         * @category Best Practices
         * @fixable
         */
        'no-implicit-coercion': [
            'error',
            {
                allow: ['!!']
            }
        ],


        /**
         * 禁止在全局作用域下定義變量或申明函數
         * @category Best Practices
         */
        'no-implicit-globals': 'error',


        /**
         * 禁止在 setTimeout 或 setInterval 中傳入字符串,如 setTimeout('alert("Hi!")', 100);
         * @category Best Practices
         */
        'no-implied-eval': 'error',


        /**
         * 禁止在類之外的地方使用 this
         * @category Best Practices
         * @reason this 的使用很靈活,事件回調中可以表示當前元素,函數也可以先用 this,等以後被調用的時候再 call
         */
        'no-invalid-this': 'off',


        /**
         * 禁止使用 __iterator__
         * @category Best Practices
         */
        'no-iterator': 'error',


        /**
         * 禁止使用 label
         * @category Best Practices
         */
        'no-labels': 'error',


        /**
         * 禁止使用沒必要的 {} 作爲代碼塊
         * @category Best Practices
         */
        'no-lone-blocks': 'error',


        /**
         * 禁止在循環內的函數中出現循環體條件語句中定義的變量
         * @category Best Practices
         */
        'no-loop-func': 'error',


        /**
         * 禁止使用 magic numbers
         * @category Best Practices
         */
        'no-magic-numbers': 'off',


        /**
         * 禁止出現連續的多個空格,除非是註釋前,或對齊對象的屬性、變量定義、import 等
         * @category Best Practices
         * @fixable
         */
        'no-multi-spaces': [
            'error',
            {
                ignoreEOLComments: true,
                exceptions: {
                    Property: true,
                    BinaryExpression: false,
                    VariableDeclarator: true,
                    ImportDeclaration: true
                }
            }
        ],


        /**
         * 禁止使用 \ 來換行字符串,應使用\n
         * @category Best Practices
         */
        'no-multi-str': 'error',


        /**
         * 禁止直接 new 一個類而不賦值
         * @category Best Practices
         */
        'no-new': 'error',


        /**
         * 禁止使用 new Function,比如 let x = new Function("a", "b", "return a + b");
         * @category Best Practices
         */
        'no-new-func': 'error',


        /**
         * 禁止使用 new 來生成 String, Number 或 Boolean
         * @category Best Practices
         */
        'no-new-wrappers': 'error',


        /**
         * 禁止使用 0 開頭的數字表示八進制數
         * @category Best Practices
         */
        'no-octal': 'error',


        /**
         * 禁止使用八進制的轉義符
         * @category Best Practices
         */
        'no-octal-escape': 'error',


        /**
         * 禁止對函數的參數重新賦值
         * @category Best Practices
         */
        'no-param-reassign': 'off',


        /**
         * 禁止使用 __proto__
         * @category Best Practices
         */
        'no-proto': 'error',


        /**
         * 禁止重複定義變量
         * @category Best Practices
         */
        'no-redeclare': 'error',


        /**
         * 禁止使用指定的對象屬性
         * @category Best Practices
         * @reason 它用於限制某個具體的 api 不能使用
         */
        'no-restricted-properties': 'off',


        /**
         * 禁止在 return 語句裏賦值
         * @category Best Practices
         */
        'no-return-assign': ['error', 'always'],


        /**
         * 禁止在 return 語句裏使用 await
         * @category Best Practices
         */
        'no-return-await': 'error',


        /**
         * 禁止出現 location.href = 'javascript:void(0)';
         * @category Best Practices
         */
        'no-script-url': 'error',


        /**
         * 禁止將自己賦值給自己
         * @category Best Practices
         */
        'no-self-assign': 'error',


        /**
         * 禁止將自己與自己比較
         * @category Best Practices
         */
        'no-self-compare': 'error',


        /**
         * 禁止使用逗號操作符
         * @category Best Practices
         */
        'no-sequences': 'error',


        /**
         * 禁止 throw 字面量,必須 throw 一個 Error 對象
         * @category Best Practices
         */
        'no-throw-literal': 'error',


        /**
         * 循環內必須對循環條件的變量有修改
         * @category Best Practices
         */
        'no-unmodified-loop-condition': 'error',


        /**
         * 禁止無用的表達式
         * @category Best Practices
         */
        'no-unused-expressions': [
            'error',
            {
                allowShortCircuit: true,
                allowTernary: true,
                allowTaggedTemplates: true
            }
        ],


        /**
         * 禁止出現沒用的 label
         * @category Best Practices
         * @fixable
         */
        'no-unused-labels': 'error',


        /**
         * 禁止出現沒必要的 call 或 apply
         * @category Best Practices
         */
        'no-useless-call': 'error',


        /**
         * 禁止在 catch 中僅僅只是把錯誤 throw 出去
         * @category Best Practices
         * @reason 這樣的 catch 是沒有意義的,等價於直接執行 try 裏的代碼
         */
        'no-useless-catch': 'error',


        /**
         * 禁止出現沒必要的字符串連接
         * @category Best Practices
         */
        'no-useless-concat': 'error',


        /**
         * 禁止出現沒必要的轉義
         * @category Best Practices
         * @reason 轉義可以使代碼更易懂
         */
        'no-useless-escape': 'off',


        /**
         * 禁止沒必要的 return
         * @category Best Practices
         * @reason 沒必要限制 return
         * @fixable
         */
        'no-useless-return': 'off',


        /**
         * 禁止使用 void
         * @category Best Practices
         */
        'no-void': 'error',


        /**
         * 禁止註釋中出現 TODO 和 FIXME
         * @category Best Practices
         * @reason TODO 很常用
         */
        'no-warning-comments': 'off',


        /**
         * 禁止使用 with
         * @category Best Practices
         */
        'no-with': 'error',


        /**
         * 使用 ES2018 中的正則表達式命名組
         * @category Best Practices
         * @reason 正則表達式已經較難理解了,沒必要強制加上命名組
         */
        'prefer-named-capture-group': 'off',


        /**
         * Promise 的 reject 中必須傳入 Error 對象,而不是字面量
         * @category Best Practices
         */
        'prefer-promise-reject-errors': 'error',


        /**
         * parseInt 必須傳入第二個參數
         * @category Best Practices
         */
        radix: 'error',


        /**
         * async 函數中必須存在 await 語句
         * @category Best Practices
         * @reason async function 中沒有 await 的寫法很常見,比如 koa 的示例中就有這種用法
         */
        'require-await': 'off',


        /**
         * 正則表達式中必須要加上 u 標誌
         * @category Best Practices
         */
        'require-unicode-regexp': 'off',


        /**
         * var 必須在作用域的最前面
         * @category Best Practices
         * @reason var 不在最前面也是很常見的用法
         */
        'vars-on-top': 'off',


        /**
         * 立即執行的函數必須符合如下格式 (function () { alert('Hello') })()
         * @category Best Practices
         * @fixable
         */
        'wrap-iife': [
            'error',
            'inside',
            {
                functionPrototypeMethods: true
            }
        ],


        /**
         * 必須使用 if (foo === 5) 而不是 if (5 === foo)
         * @category Best Practices
         * @fixable
         */
        yoda: [
            'error',
            'never',
            {
                onlyEquality: true
            }
        ],


        /**
         * 禁止使用 'strict';
         * @category Strict Mode
         * @fixable
         */
        strict: ['error', 'never'],


        /**
         * 變量必須在定義的時候賦值
         * @category Variables
         * @reason 先定義後賦值很常見
         */
        'init-declarations': 'off',


        /**
         * 禁止使用 delete
         * @category Variables
         */
        'no-delete-var': 'error',


        /**
         * 禁止 label 名稱與定義過的變量重複
         * @category Variables
         */
        'no-label-var': 'error',


        /**
         * 禁止使用指定的全局變量
         * @category Variables
         * @reason 它用於限制某個具體的變量名不能使用
         */
        'no-restricted-globals': 'off',


        /**
         * 禁止變量名與上層作用域內的定義過的變量重複
         * @category Variables
         * @reason 很多時候函數的形參和傳參是同名的
         */
        'no-shadow': 'off',


        /**
         * 禁止使用保留字作爲變量名
         * @category Variables
         */
        'no-shadow-restricted-names': 'error',


        /**
         * 禁止使用未定義的變量
         * @category Variables
         */
        'no-undef': [
            'error',
            {
                typeof: false
            }
        ],


        /**
         * 禁止將 undefined 賦值給變量
         * @category Variables
         * @fixable
         */
        'no-undef-init': 'error',


        /**
         * 禁止使用 undefined
         * @category Variables
         */
        'no-undefined': 'off',


        /**
         * 定義過的變量必須使用
         * @category Variables
         */
        'no-unused-vars': [
            'error',
            {
                vars: 'all',
                args: 'none',
                caughtErrors: 'none',
                ignoreRestSiblings: true
            }
        ],


        /**
         * 變量必須先定義後使用
         * @category Variables
         */
        'no-use-before-define': [
            'error',
            {
                functions: false,
                classes: false,
                variables: false
            }
        ],


        /**
         * callback 之後必須立即 return
         * @category Node.js and CommonJS
         * @reason Limitations 太多了
         */
        'callback-return': 'off',


        /**
         * require 必須在全局作用域下
         * @category Node.js and CommonJS
         * @reason 條件加載很常見
         */
        'global-require': 'off',


        /**
         * callback 中的 error 必須被處理
         * @category Node.js and CommonJS
         */
        'handle-callback-err': 'error',


        /**
         * 禁止直接使用 Buffer
         * @category Node.js and CommonJS
         */
        'no-buffer-constructor': 'error',


        /**
         * 相同類型的 require 必須放在一起
         * @category Node.js and CommonJS
         * @reason 太嚴格了
         */
        'no-mixed-requires': 'off',


        /**
         * 禁止直接 new require('foo')
         * @category Node.js and CommonJS
         */
        'no-new-require': 'error',


        /**
         * 禁止對 __dirname 或 __filename 使用字符串連接
         * @category Node.js and CommonJS
         */
        'no-path-concat': 'error',


        /**
         * 禁止使用 process.env.NODE_ENV
         * @category Node.js and CommonJS
         * @reason 使用很常見
         */
        'no-process-env': 'off',


        /**
         * 禁止使用 process.exit(0)
         * @category Node.js and CommonJS
         * @reason 使用很常見
         */
        'no-process-exit': 'off',


        /**
         * 禁止使用指定的模塊
         * @category Node.js and CommonJS
         * @reason 它用於限制某個具體的模塊不能使用
         */
        'no-restricted-modules': 'off',


        /**
         * 禁止使用 node 中的同步的方法,比如 fs.readFileSync
         * @category Node.js and CommonJS
         * @reason 使用很常見
         */
        'no-sync': 'off',


        /**
         * 配置數組的中括號內前後的換行格式
         * @category Stylistic Issues
         * @reason 配置項無法配製成想要的樣子
         * @fixable
         */
        'array-bracket-newline': 'off',


        /**
         * 數組的括號內的前後禁止有空格
         * @category Stylistic Issues
         * @fixable
         */
        'array-bracket-spacing': ['error', 'never'],


        /**
         * 配置數組的元素之間的換行格式
         * @category Stylistic Issues
         * @reason 允許一行包含多個元素,方便大數量的數組的書寫
         * @fixable
         */
        'array-element-newline': 'off',


        /**
         * 代碼塊如果在一行內,那麼大括號內的首尾必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'block-spacing': ['error', 'always'],


        /**
         * if 與 else 的大括號風格必須一致
         * @category Stylistic Issues
         * @reason else 代碼塊可能前面需要有一行註釋
         * @fixable
         */
        'brace-style': [
            'error', 
            '1tbs', {
                'allowSingleLine': true
        }],


        /**
         * 變量名必須是 camelcase 風格的
         * @category Stylistic Issues
         * @reason 很多 api 或文件名都不是 camelcase
         */
        camelcase: 'off',


        /**
         * 註釋的首字母必須大寫
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'capitalized-comments': 'off',


        /**
         * 對象的最後一個屬性末尾必須有逗號
         * @category Stylistic Issues
         * @fixable
         */
        'comma-dangle': 'off',


        /**
         * 逗號前禁止有空格,逗號後必須要有空格
         * @category Stylistic Issues
         * @fixable
         */
        'comma-spacing': [
            'error',
            {
                before: false,
                after: true
            }
        ],


        /**
         * 禁止在行首寫逗號
         * @category Stylistic Issues
         * @fixable
         */
        'comma-style': ['error', 'last'],


        /**
         * 用作對象的計算屬性時,中括號內的首尾禁止有空格
         * @category Stylistic Issues
         * @fixable
         */
        'computed-property-spacing': ['error', 'never'],


        /**
         * 限制 this 的別名
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'consistent-this': 'off',


        /**
         * 文件最後一行必須有一個空行
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'eol-last': 'error',


        /**
         * 函數名和執行它的括號之間禁止有空格
         * @category Stylistic Issues
         * @fixable
         */
        'func-call-spacing': ['error', 'never'],


        /**
         * 函數賦值給變量的時候,函數名必須與變量名一致
         * @category Stylistic Issues
         */
        'func-name-matching': [
            'error',
            'always',
            {
                includeCommonJSModuleExports: false
            }
        ],


        /**
         * 函數必須有名字
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'func-names': 'off',


        /**
         * 必須只使用函數聲明或只使用函數表達式
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'func-style': 'off',


        /**
         * 函數參數要麼同在一行要麼每行一個
         * @category Stylistic Issues
         * @fixable
         */
        'function-paren-newline': ['error', 'multiline'],


        /**
         * 禁止使用指定的標識符
         * @category Stylistic Issues
         * @reason 它用於限制某個具體的標識符不能使用
         */
        'id-blacklist': 'off',


        /**
         * 限制變量名長度
         * @category Stylistic Issues
         * @reason 沒必要限制變量名長度
         */
        'id-length': 'off',


        /**
         * 限制變量名必須匹配指定的正則表達式
         * @category Stylistic Issues
         * @reason 沒必要限制變量名
         */
        'id-match': 'off',


        /**
         * 箭頭函數的函數體必須與箭頭在同一行,或者被括號包裹
         * @category Stylistic Issues
         * @autofix
         */
        'implicit-arrow-linebreak': ['error', 'beside'],


        /**
         * 一個縮進必須用四個空格替代
         * @category Stylistic Issues
         * @fixable
         */
        indent: [
            'error',
            2,
            {
                SwitchCase: 1,
                flatTernaryExpressions: true
            }
        ],


        /**
         * jsx 中的屬性必須用雙引號
         * @category Stylistic Issues
         * @fixable
         */
        'jsx-quotes': ['error', 'prefer-double'],


        /**
         * 對象字面量中冒號前面禁止有空格,後面必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'key-spacing': [
            'error',
            {
                beforeColon: false,
                afterColon: true,
                mode: 'strict'
            }
        ],


        /**
         * 關鍵字前後必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'keyword-spacing': [
            'error',
            {
                before: true,
                after: true
            }
        ],


        /**
         * 單行註釋必須寫在上一行
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'line-comment-position': 'off',


        /**
         * 限制換行符爲 LF 或 CRLF
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'linebreak-style': 'off',


        /**
         * 註釋前後必須有空行
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'lines-around-comment': 'off',


        /**
         * 類的成員之間是否需要空行
         * @category Stylistic Issues
         * @reason 有時爲了緊湊需要挨在一起,有時爲了可讀性需要空一行
         * @fixable
         */
        'lines-between-class-members': 'off',


        /**
         * 代碼塊嵌套的深度禁止超過 5 層
         * @category Stylistic Issues
         */
        'max-depth': ['error', 5],


        /**
         * 限制一行的長度
         * @category Stylistic Issues
         * @reason 現在編輯器已經很智能了,不需要限制一行的長度
         */
        'max-len': 'off',


        /**
         * 限制一個文件最多的行數
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'max-lines': 'off',


        /**
         * 限制函數塊中的代碼行數
         * @category Stylistic Issues
         */
        'max-lines-per-function': 'off',


        /**
         * 回調函數嵌套禁止超過 3 層,多了請用 async await 替代
         * @category Stylistic Issues
         */
        'max-nested-callbacks': ['error', 3],


        /**
         * 函數的參數禁止超過 7 個
         * @category Stylistic Issues
         */
        'max-params': ['error', 7],


        /**
         * 限制函數塊中的語句數量
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'max-statements': 'off',


        /**
         * 限制一行中的語句數量
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'max-statements-per-line': 'off',


        /**
         * 約束多行註釋的格式
         * @category Stylistic Issues
         * @reason 能寫註釋已經不容易了,不需要限制太多
         * @fixable
         */
        'multiline-comment-style': 'off',


        /**
         * 三元表達式必須得換行
         * @category Stylistic Issues
         * @reason 三元表達式可以隨意使用
         */
        'multiline-ternary': 'off',


        /**
         * new 後面的類名必須首字母大寫
         * @category Stylistic Issues
         */
        'new-cap': [
            'error',
            {
                newIsCap: true,
                capIsNew: false,
                properties: true
            }
        ],


        /**
         * new 後面的類必須有小括號
         * @category Stylistic Issues
         * @fixable
         */
        'new-parens': 'error',


        /**
         * 鏈式調用必須換行
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'newline-per-chained-call': 'off',


        /**
         * 禁止使用 Array 構造函數
         * @category Stylistic Issues
         */
        'no-array-constructor': 'error',


        /**
         * 禁止使用位運算
         * @category Stylistic Issues
         * @reason 位運算很常見
         */
        'no-bitwise': 'off',


        /**
         * 禁止使用 continue
         * @category Stylistic Issues
         * @reason continue 很常用
         */
        'no-continue': 'off',


        /**
         * 禁止在代碼後添加內聯註釋
         * @category Stylistic Issues
         * @reason 內聯註釋很常用
         */
        'no-inline-comments': 'off',


        /**
         * 禁止 else 中只有一個單獨的 if
         * @category Stylistic Issues
         * @reason 單獨的 if 可以把邏輯表達的更清楚
         * @fixable
         */
        'no-lonely-if': 'off',


        /**
         * 禁止混用不同的操作符,比如 let foo = a && b < 0 || c > 0 || d + 1 === 0
         * @category Stylistic Issues
         * @reason 太嚴格了,可以由使用者自己去判斷如何混用操作符
         */
        'no-mixed-operators': 'off',


        /**
         * 禁止混用空格和縮進
         * @category Stylistic Issues
         */
        'no-mixed-spaces-and-tabs': 'error',


        /**
         * 禁止連續賦值,比如 a = b = c = 5
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'no-multi-assign': 'off',


        /**
         * 禁止出現超過三行的連續空行
         * @category Stylistic Issues
         * @fixable
         */
        'no-multiple-empty-lines': [
            'error',
            {
                max: 3,
                maxEOF: 1,
                maxBOF: 1
            }
        ],


        /**
         * 禁止 if 裏面有否定的表達式
         * @category Stylistic Issues
         * @reason 否定的表達式可以把邏輯表達的更清楚
         */
        'no-negated-condition': 'off',


        /**
         * 禁止使用嵌套的三元表達式,比如 a ? b : c ? d : e
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'no-nested-ternary': 'off',


        /**
         * 禁止直接 new Object
         * @category Stylistic Issues
         */
        'no-new-object': 'error',


        /**
         * 禁止使用 ++ 或 --
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'no-plusplus': 'off',


        /**
         * 禁止使用特定的語法
         * @category Stylistic Issues
         * @reason 它用於限制某個具體的語法不能使用
         */
        'no-restricted-syntax': 'off',


        /**
         * 禁止使用 tabs
         * @category Stylistic Issues
         */
        'no-tabs': 'error',


        /**
         * 禁止使用三元表達式
         * @category Stylistic Issues
         * @reason 三元表達式很常用
         */
        'no-ternary': 'off',


        /**
         * 禁止行尾有空格
         * @category Stylistic Issues
         * @fixable
         */
        'no-trailing-spaces': 'error',


        /**
         * 禁止變量名出現下劃線
         * @category Stylistic Issues
         * @reason 下劃線在變量名中很常用
         */
        'no-underscore-dangle': 'off',


        /**
         * 必須使用 !a 替代 a ? false : true
         * @category Stylistic Issues
         * @reason 後者表達的更清晰
         * @fixable
         */
        'no-unneeded-ternary': 'error',


        /**
         * 禁止屬性前有空格,比如 foo. bar()
         * @category Stylistic Issues
         * @fixable
         */
        'no-whitespace-before-property': 'error',


        /**
         * 禁止 if 後面不加大括號而寫兩行代碼
         * @category Stylistic Issues
         * @fixable
         */
        'nonblock-statement-body-position': [
            'error',
            'beside',
            {
                overrides: {
                    while: 'below'
                }
            }
        ],


        /**
         * 大括號內的首尾必須有換行
         * @category Stylistic Issues
         * @fixable
         */
        'object-curly-newline': [
            'error',
            {
                multiline: true,
                consistent: true
            }
        ],


        /**
         * 對象字面量只有一行時,大括號內的首尾必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'object-curly-spacing': [
            'error',
            'always',
            {
                arraysInObjects: true,
                objectsInObjects: false
            }
        ],


        /**
         * 對象字面量內的屬性每行必須只有一個
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'object-property-newline': 'off',


        /**
         * 禁止變量申明時用逗號一次申明多個
         * @category Stylistic Issues
         */
        'one-var': ['error', 'never'],


        /**
         * 變量申明必須每行一個
         * @category Stylistic Issues
         * @fixable
         */
        'one-var-declaration-per-line': ['error', 'always'],


        /**
         * 必須使用 x = x + y 而不是 x += y
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'operator-assignment': 'off',


        /**
         * 需要換行的時候,操作符必須放在行末
         * @category Stylistic Issues
         * @reason 有時放在第二行開始處更易讀
         * @fixable
         */
        'operator-linebreak': 'off',


        /**
         * 代碼塊首尾必須要空行
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'padded-blocks': 'off',


        /**
         * 限制語句之間的空行規則,比如變量定義完之後必須要空行
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'padding-line-between-statements': 'off',


        /**
         * 使用 ... 而不是 Object.assign
         * @category Stylistic Issues
         * @fixable
         */
        'prefer-object-spread': 'error',


        /**
         * 對象字面量的鍵名禁止用引號括起來
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'quote-props': 'off',


        /**
         * 必須使用單引號,禁止使用雙引號
         * @category Stylistic Issues
         * @fixable
         */
        quotes: [
            'error',
            'single',
            {
                avoidEscape: true,
                allowTemplateLiterals: true
            }
        ],


        /**
         * 結尾必須沒有分號
         * @category Stylistic Issues
         * @fixable
         */
        semi: ['error', 'never'],


        /**
         * 一行有多個語句時,分號前面禁止有空格,分號後面必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'semi-spacing': [
            'error',
            {
                before: false,
                after: true
            }
        ],


        /**
         * 分號必須寫在行尾,禁止在行首出現
         * @category Stylistic Issues
         * @fixable
         */
        'semi-style': ['error', 'last'],


        /**
         * 對象字面量的鍵名必須排好序
         * @category Stylistic Issues
         * @reason 沒必要限制
         */
        'sort-keys': 'off',


        /**
         * 變量申明必須排好序
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @autofix
         */
        'sort-vars': 'off',


        /**
         * if, function 等的大括號之前必須要有空格,比如 if (a) {
         * @category Stylistic Issues
         * @fixable
         */
        'space-before-blocks': ['error', 'always'],


        /**
         * 命名函數表達式括號前禁止有空格,箭頭函數表達式括號前面必須有一個空格
         * @category Stylistic Issues
         * @fixable
         */
        'space-before-function-paren': [
            'error',
            {
                anonymous: 'ignore',
                named: 'never',
                asyncArrow: 'always'
            }
        ],


        /**
         * 小括號內的首尾禁止有空格
         * @category Stylistic Issues
         * @fixable
         */
        'space-in-parens': ['error', 'never'],


        /**
         * 操作符左右必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'space-infix-ops': 'error',


        /**
         * new, typeof 等後面必須有空格,++, -- 等禁止有空格
         * @category Stylistic Issues
         * @fixable
         */
        'space-unary-ops': [
            'error',
            {
                words: true,
                nonwords: false
            }
        ],


        /**
         * 註釋的斜線或 * 後必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'spaced-comment': [
            'error',
            'always',
            {
                block: {
                    exceptions: ['*'],
                    balanced: true
                }
            }
        ],


        /**
         * case 的冒號前禁止有空格,冒號後必須有空格
         * @category Stylistic Issues
         * @fixable
         */
        'switch-colon-spacing': [
            'error',
            {
                after: false,
                before: false
            }
        ],


        /**
         * 模版字符串的 tag 之後禁止有空格,比如 tag`Hello World`
         * @category Stylistic Issues
         * @fixable
         */
        'template-tag-spacing': ['error', 'never'],


        /**
         * 文件開頭禁止有 BOM
         * @category Stylistic Issues
         * @fixable
         */
        'unicode-bom': ['error', 'never'],


        /**
         * 正則表達式必須有括號包起來
         * @category Stylistic Issues
         * @reason 沒必要限制
         * @fixable
         */
        'wrap-regex': 'off',


        /**
         * 箭頭函數能夠省略 return 的時候,必須省略,比如必須寫成 () => 0,禁止寫成 () => { return 0 }
         * @category ECMAScript 6
         * @reason 箭頭函數的返回值,應該允許靈活設置
         * @fixable
         */
        'arrow-body-style': 'off',


        /**
         * 箭頭函數只有一個參數的時候,必須加括號
         * @category ECMAScript 6
         * @reason 應該允許靈活設置
         * @fixable
         */
        'arrow-parens': 'off',


        /**
         * 箭頭函數的箭頭前後必須有空格
         * @category ECMAScript 6
         * @fixable
         */
        'arrow-spacing': [
            'error',
            {
                before: true,
                after: true
            }
        ],


        /**
         * constructor 中必須有 super
         * @category ECMAScript 6
         */
        'constructor-super': 'error',


        /**
         * generator 的 * 前面禁止有空格,後面必須有空格
         * @category ECMAScript 6
         * @fixable
         */
        'generator-star-spacing': [
            'error',
            {
                before: false,
                after: true
            }
        ],


        /**
         * 禁止對定義過的 class 重新賦值
         * @category ECMAScript 6
         */
        'no-class-assign': 'error',


        /**
         * 禁止出現難以理解的箭頭函數,比如 let x = a => 1 ? 2 : 3
         * @category ECMAScript 6
         * @fixable
         */
        'no-confusing-arrow': [
            'error',
            {
                allowParens: true
            }
        ],


        /**
         * 禁止對使用 const 定義的常量重新賦值
         * @category ECMAScript 6
         */
        'no-const-assign': 'error',


        /**
         * 禁止重複定義類
         * @category ECMAScript 6
         */
        'no-dupe-class-members': 'error',


        /**
         * 禁止重複 import 模塊
         * @category ECMAScript 6
         */
        'no-duplicate-imports': 'error',


        /**
         * 禁止使用 new 來生成 Symbol
         * @category ECMAScript 6
         */
        'no-new-symbol': 'error',


        /**
         * 禁止 import 指定的模塊
         * @category ECMAScript 6
         * @reason 它用於限制某個具體的模塊不能使用
         */
        'no-restricted-imports': 'off',


        /**
         * 禁止在 super 被調用之前使用 this 或 super
         * @category ECMAScript 6
         */
        'no-this-before-super': 'error',


        /**
         * 禁止出現沒必要的計算鍵名,比如 let a = { ['0']: 0 };
         * @category ECMAScript 6
         * @fixable
         */
        'no-useless-computed-key': 'error',


        /**
         * 禁止出現沒必要的 constructor,比如 constructor(value) { super(value) }
         * @category ECMAScript 6
         */
        'no-useless-constructor': 'error',


        /**
         * 禁止解構時出現同樣名字的的重命名,比如 let { foo: foo } = bar;
         * @category ECMAScript 6
         * @fixable
         */
        'no-useless-rename': 'error',


        /**
         * 禁止使用 var
         * @category ECMAScript 6
         * @fixable
         */
        'no-var': 'error',


        /**
         * 必須使用 a = {b} 而不是 a = {b: b}
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         * @fixable
         */
        'object-shorthand': 'off',


        /**
         * 必須使用箭頭函數作爲回調
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         * @fixable
         */
        'prefer-arrow-callback': 'off',


        /**
         * 申明後不再被修改的變量必須使用 const 來申明
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         * @fixable
         */
        'prefer-const': 'error',


        /**
         * 必須使用解構
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         */
        'prefer-destructuring': 'off',


        /**
         * 必須使用 0b11111011 而不是 parseInt('111110111', 2)
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         * @fixable
         */
        'prefer-numeric-literals': 'off',


        /**
         * 必須使用 ...args 而不是 arguments
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         */
        'prefer-rest-params': 'off',


        /**
         * 必須使用 ... 而不是 apply,比如 foo(...args)
         * @category ECMAScript 6
         * @reason apply 很常用
         * @fixable
         */
        'prefer-spread': 'off',


        /**
         * 必須使用模版字符串而不是字符串連接
         * @category ECMAScript 6
         * @reason 字符串連接很常用
         * @fixable
         */
        'prefer-template': 'off',


        /**
         * generator 函數內必須有 yield
         * @category ECMAScript 6
         */
        'require-yield': 'error',


        /**
         * ... 的後面禁止有空格
         * @category ECMAScript 6
         * @fixable
         */
        'rest-spread-spacing': ['error', 'never'],


        /**
         * import 必須按規則排序
         * @category ECMAScript 6
         * @reason 沒必要強制要求
         * @fixable
         */
        'sort-imports': 'off',


        /**
         * 創建 Symbol 時必須傳入參數
         * @category ECMAScript 6
         */
        'symbol-description': 'error',


        /**
         * ${name} 內的首尾禁止有空格
         * @category ECMAScript 6
         * @fixable
         */
        'template-curly-spacing': ['error', 'never'],


        /**
         * yield* 後面必須要有空格
         * @category ECMAScript 6
         * @fixable
         */
        'yield-star-spacing': ['error', 'after']
    }
View Code

2.4、改正錯誤的方式

有三種方法來修正錯誤:

  • 手動修正: 手動修改
  • 命令修正:npm run lint
  • 插件修正: 配合vscode 中的eslint插件

2.4.1、命令修正

src/index.js

if(!!(typeof window!=="undefined")){
    console.log("Hello window!");
}

執行命令:

 

 

執行命令:npx eslint index.js --fix

 雙重否定被刪除。

使用 npm 腳本
我們添加一個 npm scripts 來運行 ESLint 規則。

例如,假設您的 package.json 文件包含以下行:

{
"scripts": {
"lint:fix": "eslint . --fix"
}
}

現在,您只需要在命令行運行 npm run lint:fix,它將修復它可修復的內容。

"lint": "eslint --fix --ext .js,.vue src"
"lint":"eslint --fix --ext .js,.vue,.ts ."

更多命令行說明

2.4.2、插件修正

vscode中安裝插件,安裝插件後可以修正錯誤。

 設置

// ESLint 插件的配置
"editor.codeActionsOnSave": {
  "source.fixAll": true,
},

插件的使用

 插件可以修正錯誤,可以忽視錯誤。

2.5、配置ESLint

如果在同一目錄下存在多個配置文件,ESLint 將按照以下優先順序以此使用其一:

  1. .eslintrc.js
  2. .eslintrc.cjs
  3. .eslintrc.yaml
  4. .eslintrc.yml
  5. .eslintrc.json
  6. package.json

2.5.1、環境配置

要在配置文件中使用 env 鍵指定環境,並通過將每個環境設置爲 true 想啓用的環境。例如,下面是啓用瀏覽器和 Node.js 環境的例子:

{
"env": {
"browser": true,
"node": true
}
}

或者在 package.json 文件中

{
"name": "mypackage",
"version": "0.0.1",
"eslintConfig": {
"env": {
"browser": true,
"node": true
}
}
}

2.5.2、配置規則

ESLint 有大量的內置規則,你可以通過插件添加更多的規則。你也可以通過配置註釋或配置文件來修改你的項目使用哪些規則。要改變一個規則的設置,你必須把規則的 ID 設置爲這些值之一。

  • "off" 或 0 - 關閉規則
  • "warn" 或 1 - 啓用並視作警告(不影響退出)。
  • "error" 或 2 - 啓用並視作錯誤(觸發時退出代碼爲 1)

2.5.2.1、使用配置註釋

eqeqeq:使用類型安全的相等運算符 === 和 !== 而不是它們的常規運算符 == 和 != 被認爲是好的做法。

curly:當一個塊只包含一個語句時,JavaScript 允許省略大括號。然而,許多人認爲,最好的做法是永遠不要在塊周圍省略大括號,即使它們是可選的,因爲這可能導致錯誤並降低代碼的清晰度。

(1)、字符指定規則

要使用配置註釋在文件中配置規則,請使用以下格式的註釋:

/* eslint eqeqeq: "off", curly: "error" */

(2)、數字指定規則

在這個例子中,關閉 eqeqeq,啓用 curly 並視作錯誤。你也可以使用數字等價物來表示規則的嚴重程度。

/* eslint eqeqeq: 0, curly: 2 */

這個例子與上一個例子相同,只是它使用了數字代碼而不是字符串值。關閉 eqeqeq 規則,curly 規則設置爲錯誤。

(3)、指定額外選項

如果一個規則有額外的選項,你可以使用數組字面的語法來指定它們,比如:

/* eslint quotes: ["error", "double"], curly: 2 */

這個註釋爲 quotes 規則指定了“雙重”選項。數組中的第一項總是規則的嚴重程度(數字或字符串)。

  • "double"(默認值)要求儘可能使用雙引號。
  • "single" 要求儘可能使用單引號。
  • "backtick" 要求儘可能使用反斜線。

(4)、配置註釋

配置註釋可以包括描述,以解釋爲什麼註釋是必要的。描述必須出現在配置之後,並以兩個或多個連續的 - 字符與配置分開。比如。

/* eslint eqeqeq: "off", curly: "error" -- Here's a description about why this configuration is necessary. */
/* eslint eqeqeq: "off", curly: "error"
--------
Here's a description about why this configuration is necessary. */
/* eslint eqeqeq: "off", curly: "error"
* --------
* This will not work due to the line above starting with a '*' character.
*/

使用配置文件

要在配置文件中配置規則,請使用 rules 鍵和一個錯誤級別以及任何你想使用的選項。比如:

{
"rules": {
"eqeqeq": "off",
"curly": "error",
"quotes": ["error", "double"]
}
}

而在 YAML 中則是:

---
rules:
eqeqeq: off
curly: error
quotes:
- error
- double

要配置一個定義在插件中的規則,你必須在規則的 ID 前加上插件的名稱和 /。比如說:

{
"plugins": [
"plugin1"
],
"rules": {
"eqeqeq": "off",
"curly": "error",
"quotes": ["error", "double"],
"plugin1/rule1": "error"
}
}

而在 YAML 中則是:

---
plugins:
- plugin1
rules:
eqeqeq: 0
curly: error
quotes:
- error
- "double"
plugin1/rule1: error

在這些配置文件中,規則 plugin1/rule1 來自名爲 plugin1 的插件。你也可以在配置註釋中使用這種格式,比如:

/* eslint "plugin1/rule1": "error" */

注意:當從插件中指定規則時,確保省略 eslint-plugin-。ESLint 只在內部使用無前綴的名字來定位規則。

2.5.3、禁用規則

使用配置註釋

(1)、禁用所有規則

要在你的文件中暫時禁用規則警告,可以使用以下格式的塊狀註釋:

/* eslint-disable */

alert('foo');

/* eslint-enable */

(2)、禁用特定規則

你還可以禁用或啓用特定規則的警告:

/* eslint-disable no-alert, no-console */

alert('foo');
console.log('bar');

/* eslint-enable no-alert, no-console */

注意/* eslint-enable */ 沒有列出任何特定的規則將導致所有被禁用的規則被重新啓用。

要禁用整個文件中的規則警告,在文件的頂部寫入 /* eslint-disable */ 塊註釋:

/* eslint-disable */

alert('foo');

你還可以在整個文件範圍內禁用或啓用特定規則:

/* eslint-disable no-alert */

alert('foo');

爲了確保永遠不會使用一個規則(無論未來是否會有任何啓用/禁用行):

/* eslint no-alert: "off" */

alert('foo');

(3)、禁用特定行規則

要禁用某一特定行的所有規則,請使用以下格式之一的行或塊註釋:

alert('foo'); // eslint-disable-line

// eslint-disable-next-line
alert('foo');

/* eslint-disable-next-line */
alert('foo');

alert('foo'); /* eslint-disable-line */

(4)、要禁用某一特定行的特定規則:

alert('foo'); // eslint-disable-line no-alert

// eslint-disable-next-line no-alert
alert('foo');

alert('foo'); /* eslint-disable-line no-alert */

/* eslint-disable-next-line no-alert */
alert('foo');

(5)、要禁用一個特定行的多個規則:

alert('foo'); // eslint-disable-line no-alert, quotes, semi

// eslint-disable-next-line no-alert, quotes, semi
alert('foo');

alert('foo'); /* eslint-disable-line no-alert, quotes, semi */

/* eslint-disable-next-line no-alert, quotes, semi */
alert('foo');

/* eslint-disable-next-line
no-alert,
quotes,
semi
*/
alert('foo');

semi:

字符串選項:

  • "always"(默認值)要求在語句的結尾處使用分號。
  • "never" 不允許將分號作爲語句的結尾(除非用於區分以 [(/+ 或 - 開頭的語句)。

對象選項("always" 時 ):

  • "omitLastInOneLineBlock": true 忽略一個塊中的最後一個分號,因爲它的大括號(以及該塊的內容)都在同一行中。

對象選項("never" 時):

  • "beforeStatementContinuationChars": "any"(默認值) [(/+ 或 - 開頭,則忽略語句末尾的分號(或缺少分號)。
  • "beforeStatementContinuationChars": "always" 如果下一行以 [(/+ 或 - 開頭,則要求在語句的末尾加上分號。
  • "beforeStatementContinuationChars": "never" 不允許將分號作爲語句的結尾,如果它不會造成 ASI 危險,即使下一行以 [(/+ 或 - 開頭。

注意beforeStatementContinuationChars 不適用於類域,因爲類域不是語句。

上述所有方法也適用於插件規則。比如,要禁用 eslint-plugin-example 的 rule-name 規則,將插件的名稱(example)和規則的名稱(rule-name)合併爲 example/rule-name

foo(); // eslint-disable-line example/rule-name
foo(); /* eslint-disable-line example/rule-name */

配置註釋可以包括說明,以解釋爲什麼註釋是必要的。描述必須在配置之後,並且需要用兩個或多個連續的 - 字符與配置分開。比如:

// eslint-disable-next-line no-console -- Here's a description about why this configuration is necessary.
console.log('hello');

/* eslint-disable-next-line no-console --
* Here's a very long description about why this configuration is necessary
* along with some additional information
**/
console.log('hello');

注意:禁用文件一部分的警告的註釋告訴 ESLint 不要報告被禁用的代碼違反規則。然而,ESLint 仍然解析整個文件,所以禁用的代碼仍然需要是語法上有效的 JavaScript。

使用配置文件

要在配置文件中禁用一組文件的規則,請使用 overrides 鍵和 files 鍵。比如:

{
"rules": {...},
"overrides": [
{
"files": ["*-test.js","*.spec.js"],
"rules": {
"no-unused-expressions": "off"
}
}
]
}

no-unused-expressions:一個未使用的表達式對程序的狀態沒有影響,表明是一個邏輯錯誤。

例如,n + 1; 不是一個語法錯誤,但它可能是一個打字錯誤,程序員的意思是一個賦值語句 n += 1; 。有時,這種未使用的表達式可能會被生產環境中的一些構建工具消除,這可能會破壞應用邏輯。

禁用內聯註釋

要禁用所有內聯配置註釋,請使用 noInlineConfig 設置。比如:

{
"rules": {...},
"noInlineConfig": true
}

這個設置類似於 –no-inline-config CLI 選項。

2.5.4、配置文件中的 ignorePatterns

你可以在你的配置文件中使用 ignorePatterns 來告訴 ESLint 忽略特定的文件和目錄。ignorePatterns 模式遵循與 .eslintignore 相同的規則。參見.eslintignore 文檔瞭解更多內容。

{
    "ignorePatterns": ["temp.js", "**/vendor/*.js"],
    "rules": {
        //...
    }
}
  • ignorePatterns 中的 glob 模式是相對於配置文件所在的目錄而言的。
  • 你不能在 overrides 屬性中使用 ignorePatterns 屬性。
  • 在 .eslintignore 中定義的模式優先於配置文件的 ignorePatterns 屬性。

如果 glob 模式以 / 開頭,該模式是相對於配置文件的基本目錄而言的。例如,lib/.eslintrc.json 中的 /foo.js 會匹配 lib/foo.js,而不是匹配lib/subdir/foo.js

如果配置是通過 --config CLI 選項提供的,配置中以 / 開頭的忽略模式是相對於當前工作目錄的,而不是給定配置的基本目錄。例如,如果使用 --config configs/.eslintrc.json,配置中的忽略模式是基於 . 而不是 ./configs

2.5.5.eslintignore 文件

你可以通過在項目的根目錄下創建 .eslintignore 文件來告訴 ESLint 要忽略哪些文件和目錄。.eslintignore 文件是一個純文本文件,其中每一行都是一個 glob 模式,表示哪些路徑應該被省略掉。例如,下面的內容將忽略所有的 JavaScript 文件:

**/*.js

當運行 ESLint 時,在決定要檢查的文件範圍前,它會在當前工作目錄中尋找 .eslintignore 文件。如果找到該文件,那麼在遍歷目錄時就會應用這些偏好。每次只能使用一個 .eslintignore 文件,且僅會使用當前工作目錄中的 .eslintignore 文件。

Glob 使用 node-ignore 進行匹配,因此有許多特性:

  • 以 # 開頭的行被視爲註釋,不影響忽略模式。
  • 路徑是相對於當前工作目錄的。這也適用於通過 --ignore-pattern命令傳遞的路徑。
  • 前面有 ! 的行是否定模式,重新包括被先前模式忽略的模式。
  • 忽略模式的行爲與 .gitignore 規範一致。

特別要注意的是,像 .gitignore 文件一樣,所有用作 .eslintignore 和 --ignore-pattern 的模式的路徑必須使用正斜槓作爲路徑分隔符。

# Valid
/root/src/*.js

# Invalid
\root\src\*.js

請參閱 .gitignore 的規範,瞭解更多有效的語法實例。

除了 .eslintignore 文件中的任何模式外,ESLint 總是遵循一些隱含的忽略規則,即使通過了 --no-ignore 標誌。這些隱含的規則如下:

  • 忽略 node_modules/
  • 忽略點文件(除了 .eslintrc.*),以及點文件夾和它們的內容

這些規則也有一些例外:

  • 如果要檢查的路徑是一個 glob 模式或目錄路徑,並且是點文件夾,則檢查所有點文件和點文件夾,包括目錄結構深處的點文件和點文件夾。

    例如,eslint .config/ 將對 .config 目錄下的所有點文件夾和點文件進行檢查,包括一級子目錄以及在目錄結構中更深的子目錄。

  • 如果要檢查的路徑是一個特定的文件路徑,並且通過了 --no-ignore 標誌,ESLint 將檢查該文件,而不考慮隱含的忽略規則。

    例如,eslint .config/my-config-file.js --no-ignore 將檢查 my-config-file.js。需要注意的是,同樣的命令如果沒有 --no-ignore 行,就不會對 my-config-file.js 文件進行檢測。

  • 通過 --ignore-pattern 或 .eslintignore 指定的 Allowlist 和 denylist 規則會優先於隱含的忽略規則。

    例如,在這種情況下,.build/test.js 是允許列表的理想文件。因爲默認忽略了所有點文件夾及其子文件,.build 必須首先要處於允許列表中,這樣 eslint 纔會知道它的子文件。然後,.build/test.js 必須被明確地列入允許列表,而其餘的內容則被拒絕列表。這可以通過以下 .eslintignore 文件完成:

    # Allowlist 'test.js' in the '.build' folder
    # But do not allow anything else in the '.build' folder to be linted
    !.build
    .build/*
    !.build/test.js

    與下面的 --ignore-pattern 一樣:

    eslint --ignore-pattern '!.build' --ignore-pattern '.build/*' --ig

2.5.6、配置插件

ESLint 支持使用第三方插件。在使用插件之前,你必須使用 npm 安裝它。

要在配置文件內配置插件,請使用 plugins 鍵,它應該是由插件名稱組成的列表。可以省略插件名稱中的 eslint-plugin- 前綴。

{
    "plugins": [
        "plugin1",
        "eslint-plugin-plugin2"
    ]
}

安裝插件:eslint-plugin-html檢查html中的語法

 配置文件:

  plugins: ["html"],

2.6、在vite與vue3中使用eslint

2.6.1、創建一個vite項目

npm create vite@latest

package.json配置

上圖爲控制檯輸入npm run dev後,展示的內容,爲了獲取本地IP,可以在配置的時候加上--host,方便自動獲取本地網絡地址;由於Vite的快是因爲它將代碼分爲依賴和源碼,依賴大多數時間不會改變,所以在開發運行中,依賴只會請求一次,而如果我們更新了依賴,瀏覽器沒有同步更新就可能會造成運行錯誤,所以可以在腳本內添加–force來避免錯誤,每次啓動運行腳本就會更新依賴,避免瀏覽器的強緩存所帶來的影響,具體內容可以去Vite官網查看學習,這裏不再展開。下圖是腳本的配置:

將原來的"dev": "vite" 🔀 "dev": "vite --force --host"進行替換,這樣就可以輸出網絡訪問地址,每次運行也會更新依賴內容。

2.6.2、集成eslint

1.安裝ESLint

npm add -D eslint

2.初始化ESLint配置

npx eslint --init

3.安裝vite-plugin-eslint(eslint結合vite使用)

// 說明: 該包是用於配置vite運行的時候自動檢測eslint規範 不符合頁面會報錯
npm add -D vite-plugin-eslint

 4.配置vite.config.ts文件

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import eslintPlugin from 'vite-plugin-eslint';

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [
        vue(),
        eslintPlugin({
            include: ['src/**/*.ts', 'src/**/*.vue', 'src/*.ts', 'src/*.vue'],
        }),
    ],
    resolve: {
        // 配置路徑別名
        alias: {
            '@': '/src',
        },
    },
});

2.6.3、指定解析器

如果這時候就到這裏結束了,則會出現:Parsing error: '>' expected.eslint的錯誤,

默認情況下,ESLint 使用Espree 作爲其解析器。 [...] 要指定 npm 模塊用作解析器,請使用 .eslintrc 文件中的 parser 選項指定它。

安裝vue-eslint-parser

npm i -D vue-eslint-parser

修改配置文件

    parser: 'vue-eslint-parser',
    parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'moudule',
        parser: '@typescript-eslint/parser',
    },
'@typescript-eslint/no-explicit-any': 'off', // 允許ts使用any

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章