前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue3学习笔记(八)—— Vite、ESLint

Vue3学习笔记(八)—— Vite、ESLint

作者头像
张果
发布2023-02-03 15:09:14
8.1K0
发布2023-02-03 15:09:14
举报
文章被收录于专栏:软件开发软件开发

一、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 项目,非常简单:

代码语言:javascript
复制
$ 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:

代码语言:javascript
复制
$ npm create vite@latest

使用 Yarn:

代码语言:javascript
复制
$ yarn create vite

使用 PNPM:

代码语言:javascript
复制
$ pnpm create vite

?code .可以使用visual studio code打开代码编辑窗口。

1.3、错误处理

1.3.1、导入自定义模块错误

vite+Ts+Vue3搭建的项目中,把Ts类型文件抽离出去,再导入到页面组件时,出现“导入路径不能以“.ts”扩展名结束”的爆红错误,但这个错误并不影响项目运行。

?解决方法:

代码语言:javascript
复制
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文件

代码语言:javascript
复制
{
  "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" }]
}

增加:

代码语言:javascript
复制
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }

1.3.2、导入内置模块错误

在vite.config.ts 配置 报错?找不到模块“path”或其相应的类型声明

?解决方法:

代码语言:javascript
复制
npm install @types/node --save-dev

1.3.3、找不到模块“./App.vue”或其相应的类型声明。ts(2307)

?解决方法:在vite-env.d.ts文件中增加以下声明:

代码语言:javascript
复制
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?从你的?环境目录?中的下列文件加载额外的环境变量:

代码语言:javascript
复制
.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 处理的代码。例如下面这些环境变量:

代码语言:javascript
复制
VITE_SOME_KEY=123
DB_PASSWORD=foobar

只有?VITE_SOME_KEY?会被暴露为?import.meta.env.VITE_SOME_KEY?提供给客户端源码,而?DB_PASSWORD?则不会。

代码语言:javascript
复制
console.log(import.meta.env.VITE_SOME_KEY) // 123
console.log(import.meta.env.DB_PASSWORD) // ?developer/article/2213249/undefined

此外,Vite 使用?dotenv-expand?来直接拓展变量。想要了解更多相关语法,请查看?它们的文档

请注意,如果想要在环境变量中使用?$?符号,则必须使用?\?对其进行转义。

代码语言:javascript
复制
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证书

代码语言:javascript
复制
cd [project folder]

mkdir keys

cd keys
mkcert create-ca
再根据ca证书生成cert证书
代码语言:javascript
复制
# mkcert create-cert [options] # options 参见npm文档

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

安装证书

?修改vite.config文件

代码语言:javascript
复制
    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, 已经帮你生成好了证书,直接引入该插件即可。

代码语言:javascript
复制
// 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?包?获取更多细节。

示例:

代码语言:javascript
复制
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 }?的数组。

当使用文件系统路径的别名时,请始终使用绝对路径。相对路径的别名值会原封不动地被使用,因此无法被正常解析。

更高级的自定义解析方法可以通过?插件?实现。

代码语言:javascript
复制
  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

代码语言:javascript
复制
$maincolor:#00f;

vite.config

代码语言:javascript
复制
  css:
  {
    preprocessorOptions:{
      scss:{
        additionalData:`@import "@/assets/scss/global.scss";`
      }
    }
  }

Counter.vue

代码语言:javascript
复制
<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

代码语言:javascript
复制
@mycolor:#f00;

vite.config

代码语言:javascript
复制
  css:
  {
    preprocessorOptions:{
      scss:{
        additionalData:`@import "@/assets/scss/global.scss";`
      },
      less:{
        additionalData:`@import "@/assets/less/global.less";`        
      }
    }
  } 

Counter.vue

代码语言:javascript
复制
<style lang="less" scoped>
@bgcolor: #fde;
.cls1 {
  background: @bgcolor;
  color: @mycolor;
}
</style>

运行:

1.4.7、设置最终构建的浏览器兼容目标

??与||的区别

//或运算如果为0,null,?developer/article/2213249/undefined,false,""则取表达式2的值

let v=100;

let c=v||"默认值1";

console.log(c);

//??如果第1个表达式的值为?developer/article/2213249/undefined,null则取表达式2的值,否则取表达式1的值,ES2020新增加

let vv=null;

let cc=vv??"默认值2";

let dd=vv===null||vv===?developer/article/2213249/undefined?"默认值2":vv;

console.log(cc);

let c=1;??//或运算如果为0,null,?developer/article/2213249/undefined,false,""则取表达式2的值,否则取表达式1的值

let v=c||2;

console.log(v);

let e=null;?//??如果第1个表达式的值为?developer/article/2213249/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 文档?获取更多细节。

代码语言:javascript
复制
<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。

代码语言:javascript
复制
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?命令来执行应用的构建。

代码语言:javascript
复制
$ npm run build

默认情况下,构建会输出到?dist?文件夹中。你可以部署这个?dist?文件夹到任何你喜欢的平台。

本地测试应用

当你构建完成应用后,你可以通过运行?npm run preview?命令,在本地测试该应用。

代码语言:javascript
复制
$ npm run build
$ npm run preview

vite preview?命令会在本地启动一个静态 Web 服务器,将?dist?文件夹运行在?http://localhost:4173。这样在本地环境下查看该构建产物是否正常可用就方便多了。

你可以通过?--port?参数来配置服务的运行端口。

代码语言:javascript
复制
{
  "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 将自动尝试下一个可用端口,所以这可能不是最终监听的服务器端口。

示例:

代码语言:javascript
复制
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

为开发服务器配置 CORS。此功能默认启用并支持任何来源。可传递一个?options 对象?来进行配置,或者传递?false?来禁用此行为。

1.4.14、使用插件

Vite 可以使用插件进行扩展,这得益于 Rollup 优秀的插件接口设计和一部分 Vite 独有的额外选项。这意味着 Vite 用户可以利用 Rollup 插件的强大生态系统,同时根据需要也能够扩展开发服务器和 SSR 功能。

添加一个插件

若要使用一个插件,需要将它添加到项目的?devDependencies?并在?vite.config.js?配置文件中的?plugins?数组中引入它。例如,要想为传统浏览器提供支持,可以按下面这样使用官方插件?@vitejs/plugin-legacy

代码语言:javascript
复制
$ npm add -D @vitejs/plugin-legacy
代码语言:javascript
复制
// 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 推荐的值。

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 及更低版本。

按使用统计

> 5%:全球使用统计选择的浏览器版本。还可以使用>=,<、<=。 > 5% in US:使用美国使用情况统计。它接受两个字母的国家代码。 > 5% in alt-AS:使用亚洲地区的使用统计。所有地区代码的列表,可以在caniuse-lite/data/regions中找到。 > 5% in my stats:使用自定义使用数据。 > 5% in browserslist-config-mycompany stats:使用来自 browserslist-config-mycompany/browserslist-stats.json?自定义数据。 cover 99.5%:提供覆盖范围的最流行的浏览器。 cover 99.5% in US:同上,两个字母的国家代码。 cover 99.5% in my stats:使用自定义数据。

最新版本

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 版本。

最新版本

  • 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 版本。

在项目根目录中,查询选择了哪些浏览器。

代码语言:javascript
复制
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

代码语言:javascript
复制
yarn add vite-plugin-html -D

代码语言:javascript
复制
npm i vite-plugin-html -D
使用
  • 在?index.html?中增加 EJS 标签,例如
代码语言:javascript
复制
<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?中配置,该方式可以按需引入需要的功能即可
代码语言:javascript
复制
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',
            },
          },
        ],
      },
    }),
  ],
})

多页应用配置

代码语言:javascript
复制
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

默认压缩配置

代码语言:javascript
复制
    collapseWhitespace: true,
    keepClosingSlash: true,
    removeComments: true,
    removeRedundantAttributes: true,
    removeScriptTypeAttributes: true,
    removeStyleLinkTypeAttributes: true,
    useShortDoctype: true,
    minifyCSS: true,
运行示例
代码语言:javascript
复制
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 文件。导入这样的文件会返回一个相应的模块对象:

代码语言:javascript
复制
/* example.module.css */
.red {
  color: red;
}
代码语言:javascript
复制
import classes from './example.module.css'
document.getElementById('foo').className = classes.red

CSS modules 行为可以通过?css.modules?选项?进行配置。

如果?css.modules.localsConvention?设置开启了 camelCase 格式变量名转换(例如?localsConvention: 'camelCaseOnly'),你还可以使用按名导入。

代码语言:javascript
复制
// .apply-color -> applyColor
import { applyColor } from './example.module.css'
document.getElementById('foo').className = applyColor
代码语言:javascript
复制
<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

代码语言:javascript
复制
.red{
    color:red;
}

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

1.4.16、禁用 CSS 注入页面

自动注入 CSS 内容的行为可以通过??inline?参数来关闭。在关闭时,被处理过的 CSS 字符串将会作为该模块的默认导出,但样式并没有被注入到页面中。

代码语言:javascript
复制
import './foo.css' // 样式将会注入页面
import otherStyles from './bar.css?inline' // 样式不会注入页面

1.4.17、静态资源处理

导入一个静态资源会返回解析后的 URL:

代码语言:javascript
复制
import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

添加一些特殊的查询参数可以更改资源被引入的方式:

代码语言:javascript
复制
// 显式加载资源为一个 URL
import assetAsURL from './asset.js?url'
代码语言:javascript
复制
// 以字符串形式加载资源
import assetAsString from './shader.glsl?raw'
代码语言:javascript
复制
// 加载为 Web Worker
import Worker from './worker.js?worker'
代码语言:javascript
复制
// 在构建时 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 中文官方网站]:http://eslint.cn/

2.2、第一个ESLint项目

前提条件:内置 SSL 支持的?Node.js?版本(^12.22.0^14.17.0?或?>=16.0.0),如果你使用的是官方 Node.js 发行版,那么已经内置了 SSL 支持。

你可以使用该命令安装并配置 ESLint:

代码语言:javascript
复制
npm init @eslint/config

注意:使用?npm init @eslint/config?时,运行目录需要已经有?package.json?文件了。如果还没有该文件,请确保在此之前运行?npm init?或?yarn init

在此之后,你可以像这样使用 ESLint 检查任一文件或目录:

代码语言:javascript
复制
npx eslint yourfile.js

# 或

yarn run eslint yourfile.js

也可以全局安装 ESLint 而不仅限于本地(使用?npm install eslint --global)。但并不推荐这样做,因为无论使用哪种安装方式,你都需要在本地安装插件和可共享配置。

1、创建一个空项目、初始化为node项目

?2、配置ESLint项目

?3、创建index.js文件

代码语言:javascript
复制
for(var i=0;i<100;i--){}

注意这里故意把i++写成了i--,代码块中没有内容。

4、执行eslint检查

发现了2个错误

2.3、常见错误与问题

ESLint完整规则(rules)地址:https://eslint.org/docs/rules/

?规则解释一:

代码语言:javascript
复制
"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,//变量初始化时不能直接给它赋值为?developer/article/2213249/undefined
"no-?developer/article/2213249/undefined": 2,//不能使用?developer/article/2213249/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"]//禁止尤达条件

规则解释二:

代码语言:javascript
复制
{
        /**
         * 禁止 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 表达式比较的对象必须是 '?developer/article/2213249/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 不是 ?developer/article/2213249/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
            }
        ],


        /**
         * 禁止将 ?developer/article/2213249/undefined 赋值给变量
         * @category Variables
         * @fixable
         */
        'no-undef-init': 'error',


        /**
         * 禁止使用 ?developer/article/2213249/undefined
         * @category Variables
         */
        'no-?developer/article/2213249/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']
    }

2.4、改正错误的方式

有三种方法来修正错误:

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

2.4.1、命令修正

src/index.js

代码语言:javascript
复制
if(!!(typeof window!=="?developer/article/2213249/undefined")){
    console.log("Hello window!");
}

执行命令:

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

?双重否定被删除。

使用 npm 脚本 我们添加一个 npm scripts 来运行 ESLint 规则。

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

代码语言:javascript
复制
{
"scripts": {
"lint:fix": "eslint . --fix"
}
}

现在,您只需要在命令行运行 npm run lint:fix,它将修复它可修复的内容。

代码语言:javascript
复制
"lint": "eslint --fix --ext .js,.vue src"
代码语言:javascript
复制
"lint":"eslint --fix --ext .js,.vue,.ts ."

更多命令行说明

2.4.2、插件修正

vscode中安装插件,安装插件后可以修正错误。

?设置

代码语言:javascript
复制
// 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 环境的例子:

代码语言:javascript
复制
{
    "env": {
        "browser": true,
        "node": true
    }
}

或者在?package.json?文件中

代码语言:javascript
复制
{
    "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)、字符指定规则

要使用配置注释在文件中配置规则,请使用以下格式的注释:

代码语言:javascript
复制
/* eslint eqeqeq: "off", curly: "error" */

(2)、数字指定规则

在这个例子中,关闭?eqeqeq,启用?curly?并视作错误。你也可以使用数字等价物来表示规则的严重程度。

代码语言:javascript
复制
/* eslint eqeqeq: 0, curly: 2 */

这个例子与上一个例子相同,只是它使用了数字代码而不是字符串值。关闭?eqeqeq?规则,curly?规则设置为错误。

(3)、指定额外选项

如果一个规则有额外的选项,你可以使用数组字面的语法来指定它们,比如:

代码语言:javascript
复制
/* eslint quotes: ["error", "double"], curly: 2 */

这个注释为?quotes?规则指定了“双重”选项。数组中的第一项总是规则的严重程度(数字或字符串)。

  • "double"(默认值)要求尽可能使用双引号。
  • "single"?要求尽可能使用单引号。
  • "backtick"?要求尽可能使用反斜线。

(4)、配置注释

配置注释可以包括描述,以解释为什么注释是必要的。描述必须出现在配置之后,并以两个或多个连续的?-?字符与配置分开。比如。

代码语言:javascript
复制
/* eslint eqeqeq: "off", curly: "error" -- Here's a description about why this configuration is necessary. */
代码语言:javascript
复制
/* eslint eqeqeq: "off", curly: "error"
    --------
    Here's a description about why this configuration is necessary. */
代码语言:javascript
复制
/* eslint eqeqeq: "off", curly: "error"
 * --------
 * This will not work due to the line above starting with a '*' character.
 */
使用配置文件

要在配置文件中配置规则,请使用?rules?键和一个错误级别以及任何你想使用的选项。比如:

代码语言:javascript
复制
{
    "rules": {
        "eqeqeq": "off",
        "curly": "error",
        "quotes": ["error", "double"]
    }
}

而在 YAML 中则是:

代码语言:javascript
复制
---
rules:
  eqeqeq: off
  curly: error
  quotes:
    - error
    - double

要配置一个定义在插件中的规则,你必须在规则的 ID 前加上插件的名称和?/。比如说:

代码语言:javascript
复制
{
    "plugins": [
        "plugin1"
    ],
    "rules": {
        "eqeqeq": "off",
        "curly": "error",
        "quotes": ["error", "double"],
        "plugin1/rule1": "error"
    }
}

而在 YAML 中则是:

代码语言:javascript
复制
---
plugins:
  - plugin1
rules:
  eqeqeq: 0
  curly: error
  quotes:
    - error
    - "double"
  plugin1/rule1: error

在这些配置文件中,规则?plugin1/rule1?来自名为?plugin1?的插件。你也可以在配置注释中使用这种格式,比如:

代码语言:javascript
复制
/* eslint "plugin1/rule1": "error" */

注意:当从插件中指定规则时,确保省略?eslint-plugin-。ESLint 只在内部使用无前缀的名字来定位规则。

2.5.3、禁用规则

使用配置注释

(1)、禁用所有规则

要在你的文件中暂时禁用规则警告,可以使用以下格式的块状注释:

代码语言:javascript
复制
/* eslint-disable */

alert('foo');

/* eslint-enable */

(2)、禁用特定规则

你还可以禁用或启用特定规则的警告:

代码语言:javascript
复制
/* eslint-disable no-alert, no-console */

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

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

注意/* eslint-enable */?没有列出任何特定的规则将导致所有被禁用的规则被重新启用。

要禁用整个文件中的规则警告,在文件的顶部写入?/* eslint-disable */?块注释:

代码语言:javascript
复制
/* eslint-disable */

alert('foo');

你还可以在整个文件范围内禁用或启用特定规则:

代码语言:javascript
复制
/* eslint-disable no-alert */

alert('foo');

为了确保永远不会使用一个规则(无论未来是否会有任何启用/禁用行):

代码语言:javascript
复制
/* eslint no-alert: "off" */

alert('foo');

(3)、禁用特定行规则

要禁用某一特定行的所有规则,请使用以下格式之一的行或块注释:

代码语言:javascript
复制
alert('foo'); // eslint-disable-line

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

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

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

(4)、要禁用某一特定行的特定规则:

代码语言:javascript
复制
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)、要禁用一个特定行的多个规则:

代码语言:javascript
复制
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

代码语言:javascript
复制
foo(); // eslint-disable-line example/rule-name
foo(); /* eslint-disable-line example/rule-name */

配置注释可以包括说明,以解释为什么注释是必要的。描述必须在配置之后,并且需要用两个或多个连续的?-?字符与配置分开。比如:

代码语言:javascript
复制
// 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?键。比如:

代码语言:javascript
复制
{
  "rules": {...},
  "overrides": [
    {
      "files": ["*-test.js","*.spec.js"],
      "rules": {
        "no-unused-expressions": "off"
      }
    }
  ]
}

no-unused-expressions:一个未使用的表达式对程序的状态没有影响,表明是一个逻辑错误。

例如,n + 1;?不是一个语法错误,但它可能是一个打字错误,程序员的意思是一个赋值语句?n += 1;?。有时,这种未使用的表达式可能会被生产环境中的一些构建工具消除,这可能会破坏应用逻辑。

禁用内联注释

要禁用所有内联配置注释,请使用?noInlineConfig?设置。比如:

代码语言:javascript
复制
{
  "rules": {...},
  "noInlineConfig": true
}

这个设置类似于?–no-inline-config?CLI 选项。

2.5.4、配置文件中的?ignorePatterns

你可以在你的配置文件中使用?ignorePatterns?来告诉 ESLint 忽略特定的文件和目录。ignorePatterns?模式遵循与?.eslintignore?相同的规则。参见.eslintignore?文档了解更多内容。

代码语言:javascript
复制
{
    "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 文件:

代码语言:javascript
复制
**/*.js

当运行 ESLint 时,在决定要检查的文件范围前,它会在当前工作目录中寻找?.eslintignore?文件。如果找到该文件,那么在遍历目录时就会应用这些偏好。每次只能使用一个?.eslintignore?文件,且仅会使用当前工作目录中的?.eslintignore?文件。

Glob 使用?node-ignore?进行匹配,因此有许多特性:

  • 以?#?开头的行被视为注释,不影响忽略模式。
  • 路径是相对于当前工作目录的。这也适用于通过?--ignore-pattern命令传递的路径。
  • 前面有?!?的行是否定模式,重新包括被先前模式忽略的模式。
  • 忽略模式的行为与?.gitignore 规范一致。

特别要注意的是,像?.gitignore?文件一样,所有用作?.eslintignore?和?--ignore-pattern?的模式的路径必须使用正斜杠作为路径分隔符。

代码语言:javascript
复制
# 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?文件完成:

代码语言:javascript
复制
# 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?一样:

代码语言:javascript
复制
eslint --ignore-pattern '!.build' --ignore-pattern '.build/*' --ig

2.5.6、配置插件

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

要在配置文件内配置插件,请使用?plugins?键,它应该是由插件名称组成的列表。可以省略插件名称中的?eslint-plugin-?前缀。

代码语言:javascript
复制
{
    "plugins": [
        "plugin1",
        "eslint-plugin-plugin2"
    ]
}

安装插件:eslint-plugin-html检查html中的语法

?配置文件:

代码语言:javascript
复制
  plugins: ["html"],

2.6、在vite与vue3中使用eslint

2.6.1、创建一个vite项目

代码语言:javascript
复制
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

代码语言:javascript
复制
npm add -D eslint

2.初始化ESLint配置

代码语言:javascript
复制
npx eslint --init

3.安装vite-plugin-eslint(eslint结合vite使用)

代码语言:javascript
复制
// 说明: 该包是用于配置vite运行的时候自动检测eslint规范 不符合页面会报错
npm add -D vite-plugin-eslint

?4.配置vite.config.ts文件

代码语言:javascript
复制
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

修改配置文件

代码语言:javascript
复制
    parser: 'vue-eslint-parser',
    parserOptions: {
        ecmaVersion: 2020,
        sourceType: 'moudule',
        parser: '@typescript-eslint/parser',
    },
代码语言:javascript
复制
'@typescript-eslint/no-explicit-any': 'off', // 允许ts使用any
本文参与?腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客?前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、vite
    • 1.1、概要
      • 1.2、使用vite构建第一个vue项目
        • 1.3、错误处理
          • 1.3.1、导入自定义模块错误
          • 1.3.2、导入内置模块错误
          • 1.3.3、找不到模块“./App.vue”或其相应的类型声明。ts(2307)
        • 1.4、配置
          • 1.4.0、共享配置
          • 1.4.1、主机与端口配置
          • 1.4.2、HTTPS
          • 1.4.3、自动打开浏览器
          • 1.4.4、别名
          • 1.4.5、SCSS
          • 1.4.6、less
          • 1.4.7、设置最终构建的浏览器兼容目标
          • 1.4.8、指定输出路径
          • 1.4.9、静态资源目录
          • 1.4.10、内联资源大小限定
          • 1.4.11、拆分CSS代码
          • 1.4.12、压缩空间
          • 1.4.13、预览
          • 1.4.14、使用插件
          • 1.4.15、CSS Modules
          • 1.4.16、禁用 CSS 注入页面
          • 1.4.17、静态资源处理
      • 二、ESLint
        • 2.1、概要
          • 2.2、第一个ESLint项目
            • 2.3、常见错误与问题
              • 2.4、改正错误的方式
                • 2.4.1、命令修正
                • 2.4.2、插件修正
              • 2.5、配置ESLint
                • 2.5.1、环境配置
                • 2.5.2、配置规则
                • 2.5.3、禁用规则
                • 2.5.4、配置文件中的?ignorePatterns
                • 2.5.5.eslintignore?文件
                • 2.5.6、配置插件
              • 2.6、在vite与vue3中使用eslint
                • 2.6.1、创建一个vite项目
                • 2.6.2、集成eslint
                • 2.6.3、指定解析器
            相关产品与服务
            检测工具
            域名服务检测工具(Detection Tools)提供了全面的智能化域名诊断,包括Whois、DNS生效等特性检测,同时提供SSL证书相关特性检测,保障您的域名和网站健康。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
            http://www.vxiaotou.com