NPM 插件 ESLint
ESLint
是一个 javascript
代码检测工具,例如未使用的变量,未定义的引用,比较时使用三等,禁止不必要的括号 等等代码质量检测, 其出现大大提高了团队协作的代码规范统一性,以及个人的代码质量,深受 web
开发者们的青睐。但是其众多的配置参数,语法规则,也同样让人迷糊。好在各大 web 框架的脚手架中都内置了 ESLint
插件,渐渐的像 ESLint
看齐,开发者们无需再过多手动配置,即可享受 ESLint
带来的团队及个人效益。但是考虑到并不是所有的框架都内置了并且有许多像我一样爱折腾的朋友们,我们还是需要对其一探究竟。
话不多说,我们直接上代码。
NPM ESLint 命令行
mkdir eslint-app && cd eslint-app // 创建空目录并进入目录
npm init // 初始化 npm
touch index.js // 创建入口文件
npm i eslint -D // 安装 eslint 依赖
复制代码
我们创建了一个新的目录,并且安装了好了 ESLint
,接着我们在 index.js
中写入代码
const hello = 'hello';
复制代码
在package.json
的 scripts
选项中加入一条检测脚本,代表我们要对 目录下所有的 js 文件进行 ESLint
检测
"scripts": {
"lint": "eslint ."
}
复制代码
紧接着执行 npm run lint
,不出意外的话,应该会出现一个报错,提示我们需要一个 ESLint
配置文件
因此,我们先在根目录下手动创建一个 eslint 配置文件,命名可以是 .eslintrc.json
,,eslintrc.js
,.eslintrc.yaml
,甚至配置在 package.json
中,我这里使用了 .eslintrc.json
,并添加了以下配置代码
{
"env": { // 全局环境变量
"browser": true // 浏览器环境
},
"extends": "eslint:recommended", // 继承 eslint 默认配置
"parserOptions": { // 指定 javaScript 语言类型和风格
"sourceType": "module" // 导入方式设定为模块导入
},
"rules": { // 配置规则
"no-unused-vars": 1, // 警告不允许出现未使用的变量
"semi": [1, "always"] // 警告强制加上句尾分号
}
}
复制代码
.eslintrc
即将废弃,可以使用.eslintrc.json
完全代替
配置文件已经创建好了,我们继续执行之前的 npm run lint
,如果你的 index.js
代码和我上述一样,此时终端应该出现了警告,告诉我们 index.js 定义了 hello
变量但没有使用。至此我们第一步的校验已经大功告成
许多朋友已经养成了不写分号的习惯但团队又必须要求加上句尾分号,这个时候可以用到 ESLint
自带的格式化功能,他能对我们一些比较基本的语法问题进行自动格式化,在 package.json
scripts
中添加一条格式化脚本,可以看到与 lint
的区别就是加了一个 --fix
参数
"scripts": {
"format": "eslint . --fix"
},
复制代码
紧接着我们去掉 index.js
第一行的分号,执行 npm run format
,然后回头看 index.js
, 应该发现句尾已经自动帮我们加上了分号了
eslint-webpack-plugin(eslint-loader)
自从 webpack 5 开始,eslint-loader 已经不再被 webpack 推荐,具体原因见 github.com/webpack-con…
那么问题来了,ESLint
如何与现有项目进行融合?以及在实际项目中,每次如果需要手动执行一次 lint 才能看到我们的语法错误,那岂不是是十分麻烦的?
这个时候 eslint-webpack-plugin
派上用场了,eslint-webpack-plugin
是 webpack
插件,在项目编译期间,能对我们的 js 代码进行实时的检测。我们先手动搭建一个 webpack
环境,在此项目上继续安装依赖
npm i webpack-cli webpack webpack-dev-server webpack-html-plugin eslint-webpack-plugin -D
复制代码
在 package.json
scripts 中添加一条启动脚本
"scripts": {
"start": "webpack serve"
}
复制代码
并在根目录添加 webpack.config.js
配置文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const EslintWebpackPlugin = require('eslint-webpack-plugin');
module.exports = {
mode: 'development',
entry: './index.js',
devtool: 'inline-cheap-module-source-map',
plugins: [new HtmlWebpackPlugin(), new EslintWebpackPlugin()],
devServer: {
port: 9000,
},
};
复制代码
-
手动修改
index.js
去掉句尾分号,随即运行npm start
,观察控制台会发现出现了警告,并打开浏览器输入网址http://localhost:9000/
,按下F12
,浏览器的控制台中同样出现了警 -
手动修改
index.js
加上句尾分号,随即运行npm start
,观察控制台会发现警告消失了,并观察浏览器的控制台中的警告也消失了
如果同样想支持保存即自动格式化,只需在
webpack
配置文件的EslintWebpackPlugin
,中传入{ fix: true }
选项就可以了
NPM 插件 Perttier
Prettier
又是什么?和 ESLint
又有什么关系?
上述说到 ESLint
的作用是代码质量检测,Prettier
的作用则主要是代码格式化,那不是和 ESLint
冲突了吗?并不是,ESLint
只能格式化 js/ts
文件,而 Prettier
支持多种文件
JavaScript/TypeScript
CSS/Less/SCSS
HTML
JSON/YAML/GraphQL
Markdown
Vue/React/Angular
Prettier
自身的规范更倾向于个人/团队的代码风格的规范或统一,例如每行最大长度,单引号还是双引号,等号左右空格,使用 tab 还是 空格等等,将他与 ESLint
一起协同工作犹如如虎添翼
NPM 插件 eslint-plugin-prettier
eslint-plugin-prettier
是 一个 ESLint
插件, 由 Prettier
生态提供,用于报告错误给 ESLint
npm i prettier eslint-plugin-prettier eslint-config-prettier
复制代码
eslint-config-prettier 的作用是使用
Prettier
默认推荐配置,并且关闭 eslint 自身的格式化功能,防止Prettier
和ESLint
的自动格式化的冲突
在项目根目录下添加 Prettier
配置文件 .prettierrc
{
"singleQuote": true, // 强制单引号
"semi": true // 强制句尾分号
}
复制代码
修改 index.js
const hello = 'hello';
console.log(hello);
复制代码
修改 .eslintrc.json
{
"env": {
"browser": true
},
"extends":["plugin:prettier/recommended"], // 使用 prettier 推荐配置
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
}
}
复制代码
重新执行 npm start
- 如果配置了
EslintWebpackPlugin
的fix: true
选项,会发现双引号已变成单引号,并且自动加上了分号 - 反之,则出现
eslint prettier
报错,错误的使用了双引号,并且未加句尾分号
ESlint
与 Prettier
的合作关系: 由于 ESlint
自身自动格式化功能不够完善,Prettier
代替了 ESlint
格式化能力,利用了 ESlint
的检测和提示
VS Code ESLint/Prettier 插件
似乎还漏了什么,上面的代码的提示都是在项目编译时提示,好不容易写了一大串代码,运行时发现了 n 个语法警告和报错,顿时心态炸裂
VS Code ESLint 插件
回到 VS Code
,按下 ctrl + shift + X
(mac: command + shift + X
),进入插件商店,安装 ESLint
插件,恢复 index.js
代码至以下
const hello = 'hello';
console.log(hello);
复制代码
喜出望外,编辑器未雨绸缪的提示了报错与警告,不必再等到编译时提示了,在写代码的时候我们就可以发现错误了,这就是 VS Code ESLint
插件的能力。
VS Code ESLint
插件运行需要本地项目的ESLint
相关插件和配置都存在(依赖,配置文件),但不一定要被编译。比如在webpack
中可以不使用eslint-loader
或者eslint-webpack-plugin
VS Code Prettier 插件
在项目比较大文件比较多的时候,依赖 NPM Prettier
的自动格式化可能会导致保存后需要很久才能完成,因为它需要先编译一遍 javascript,这个时候 VS Code
的 Prettier
插件的作用就体现出来了,使用上述中同样方法在插件商店安装 Prettier
插件
在项目的根目录下创建 .vscode 目录,进入目录创建 .settings.json 文件,添加以下代码
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"[javascript]": {
"editor.formatOnSave": false
},
"[javascriptreact]": {
"editor.formatOnSave": false
},
"[typescript]": {
"editor.formatOnSave": false
},
"[typescriptreact]": {
"editor.formatOnSave": false
}
}
复制代码
配置大致描述为:启用 vscode eslint
插件的保存格式化,启用 vscode
自带的保存格式化,格式化插件为 prettier
,并禁用 prettier
对 JavaScript
相关文件的格式化。
意思就是:js
格式化只通过 eslint
,其他类型文件使用 prettier
,否则2种工具同时进行格式化可能会遇到冲突。
prettier 提供的 eslint 插件赋予了 eslint 更多的格式化功能,因此,我们现在可以将 eslint 作为我们的主要格式化手段了。
再次回到 index.js
,保存,会发现代码已经被自动格式化了。此时修改 package.josn
的 scripts
的 格式化 脚本为
"format": "eslint . --ext js,ts,tsx --fix && prettier --write *"
复制代码
到了这个时候, 其实 VS Code
的 格式化已经和 NPM
的格式化冲突了,所以可以完全删除 eslint-webpack-plugin
插件了,解决冲突的同时,也大大的提高了代码的编译效率,,将检测与格式化的工作完全交给编辑器来做。这同样也是目前各大框架流行的做法,否则 webpack
中的 ESLint
也要完整解析一次代码,在项目比较大的时候特别影响编译速度,以及控制台带来的一连串警告和报错影响开发者的体验
对于需要个性化配置 prettier
的规则,可以在项目下新建 .prettierrc
的 json
文件,同样支持其他文件名称,具体见 prettier.io/docs/en/con…
ESLint配置
TypeScript
之前采用 tslint
作为 ts
代码的格式化工具,但是 tslint
有一个致命的问题就是只能支持 ts
,而eslint
对于 ts
和 js
都支持,现在 tslint
已经不维护了并推荐使用 eslint
,因此,我们可以全面拥抱 eslint
了
对于 ts, eslint 也不是添加支持,需要通过配置插件,目前全网都在使用的是 @typescript-eslint/eslint-plugin
这个插件,在 eslint 配置文件 extends 属性中,添加 plugin:@typescript-eslint/recommended
的推荐配置
另外,对于 ts 文件,还需要单独配置一下解释器,对 ts 代码进行解析
那为什么 JS 不需要呢?
eslint
默认带有一个解析器 parser
,但只转换 js,默认支持 ES5
的语法,可以通过制定 parserOptions
传递如下选项,我们文中开头提到过
"parserOptions": {
"ecmaVersion": 6, // 支持 es6 语法
"sourceType": "module",
"ecmaFeatures": {
"jsx": true // 支持 jsx 语法,如果有需要
}
}
复制代码
eslint
会对我们的代码进行校验,而 parser
的作用是将我们写的代码转换为 ESTree,eslint
会对 ESTree
进行校验。
{
"env": {
"browser": true,
},
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 6,
"ecmaFeatures": {
"jsx": true,
},
},
"parser": "@typescript-eslint/parser",
"extends": ["plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"],
}
复制代码
ESTree 只是一个 AST 的某一种规范,ESTree 本质上还是 AST
其他插件
Vue
如果你使用的是 Vue
,需要使用 VUe
官方提供的 eslint-plugin-vue 插件,主要对 Vue
的单文件组件内的模板语法进行校验
React
如果你使用的是 React
,则上述配置已经完全足够你使用了,当然,React 官方也抛出了一个 react-hooks
专门的插件 www.npmjs.com/package/esl… ,主要针对 react hooks 使用规范和依赖参数的校验。
总结
- NPM ESLint 插件 : 代码编译时时的语法检测
- NPM Prettier 插件: 代码编译时的自动格式化
- VS Code ESLint 插件: 编辑器对开发时的代码进行即时的语法检测和提示
- VS Code Prettier 插件: 编辑器对对开发时的代码进行即时的格式化
:::