ESLint
规范化介绍
规范化是我们践行前端工程化中重要的一部分。
- 为什么要有规范化标准
- 哪里需要规范化标准
- 实施规划化的方法
为什么要有规范化标准
- 软件开发需要多人协同
- 不同开发者具有不同的编码习惯和喜好
- 不同的喜好增加项目维护成本
- 每个项目或者团队需要明确统一的标准
哪里需要规范化标准
- 代码、文档、提交日志等
- 开发过程中人为编写的成果
- 代码标准化规范最为重要
实施规范化的方法
- 编码前人为的标准约定
- 通过工具实现 Lint
ESLint 介绍
目前最为主流的 JavaScript Lint 工具,用来检测 JS 代码质量。
ESLint 很容易统一开发者的编码风格。
ESLint 可以帮助开发者提升编码能力。
ESLint 安装
- 初始化项目
- 安装 ESLint 模块为开发依赖
- 通过 CLI 命令验证安装结果
yarn add eslint --save-dev
yarn add eslint --save-dev
查看 eslint 版本号,可以使用多种方式
.\node_modules\.bin\eslint -v
npx eslint -v
yarn eslint -v
.\node_modules\.bin\eslint -v
npx eslint -v
yarn eslint -v
ESLint 快速上手
ESLint 检查步骤
- 编写 “问题” 代码
- 使用 eslint 执行检测
- 完成 eslint 配置
index.js
const foo = 123;
function fn () {
console.log('hello');
console.log('eslint');
}
fn(;
syy();
const foo = 123;
function fn () {
console.log('hello');
console.log('eslint');
}
fn(;
syy();
初始化 eslint 配置,命令行交互的方式进行选择。
npx eslint --init
npx eslint --init
使用 eslint 检查代码
npx eslint .\index.js
npx eslint .\index.js
修正后代码
const foo = 123
console.log(foo)
function fn () {
console.log('hello')
console.log('eslint')
}
fn()
const foo = 123
console.log(foo)
function fn () {
console.log('hello')
console.log('eslint')
}
fn()
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'standard'
],
parserOptions: {
ecmaVersion: 12
},
rules: {
}
}
module.exports = {
env: {
browser: true,
es2021: true
},
extends: [
'standard'
],
parserOptions: {
ecmaVersion: 12
},
rules: {
}
}
ESLint 配置文件解析
可以同时设置多个属性,以下属性不是互斥的。
属性 | 描述 |
---|---|
browser | 浏览器中的全局变量 |
node | Node.js 全局变量和 Node.js 作用域 |
common.js | CommonJS 全局变量和 CommonJS 作用域(用于 Broserify/Webpack 打包的只在浏览器运行的代码) |
shared_node_browser | Node.js 和 Browser 通用全局变量 |
es6 | 启动除了 modules 以外的所有 ECMAScript 6 特性(该选项会自动设置 ecmaVersion 解析器选项为 6) |
worker | Web Workers 全局变量 |
amd | 将 requre() 和 define() 定义为像 amd 一样的全局变量 |
mocha | 添加所有的 Mocha 测试全局变量 |
jasmine | 添加所有的 Jasmine 版本 1.3 和 2.0 的测试全局变量 |
jest | Jest 全局变量 |
protractor | Protractor 全局变量 |
qunit | Quint 全局变量 |
jquery | Jquery 全局变量 |
prototype.js | Prototype.js 全局变量 |
shelljs | ShellJS全局变量 |
meteor | Meteor 全局变量 |
mongo | MongoDB 全局变量 |
applescript | AppleScript 全局变量 |
nashorn | Java 8 Nashron 全局变量 |
serviceworker | Service Worker 全局变量 |
atomtest | Atom 全局变量 |
embertest | Ember 全局变量 |
webextensions | WebExtensions 全局变量 |
greasemonkey | GreaseMonkey 全局变量 |
ESLint 配置注释
http://eslint.cn/docs/user-guide/configuring#configuring-rules
const str = '${name} is a coder'; // eslint-disable-line no-template-curly-in-string
console.log(str);
const str = '${name} is a coder'; // eslint-disable-line no-template-curly-in-string
console.log(str);
npx eslint ./index.js
npx eslint ./index.js
ESLint 结合自动化工具
- 集成之后,ESLint 一定会工作
- 项目统一,管理更加方便
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.eslint())
.pipe(plugins.eslint.format())
.pipe(plugins.eslint.failAfterError())
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('temp'));
}
module.exports = {
script
};
const script = () => {
return src('src/assets/scripts/*.js', { base: 'src' })
.pipe(plugins.eslint())
.pipe(plugins.eslint.format())
.pipe(plugins.eslint.failAfterError())
.pipe(plugins.babel({ presets: ['@babel/preset-env'] }))
.pipe(dest('temp'));
}
module.exports = {
script
};
npx eslint --init
npx eslint --init
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard'
],
parserOptions: {
ecmaVersion: 12
},
rules: {
},
globals: {
'$': 'readonly'
}
}
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard'
],
parserOptions: {
ecmaVersion: 12
},
rules: {
},
globals: {
'$': 'readonly'
}
}
ESLint 结合 webpack
module.exports = {
module: {
rules: [
{
test: /.js$/,
exlcude: /node_modules/,
use: 'eslint-loader',
enforce: 'pre'
}
]
}
}
module.exports = {
module: {
rules: [
{
test: /.js$/,
exlcude: /node_modules/,
use: 'eslint-loader',
enforce: 'pre'
}
]
}
}
npm i eslint eslint-loader --sav-dev
npm i eslint-plugin-react --save-dev
npm i eslint eslint-loader --sav-dev
npm i eslint-plugin-react --save-dev
npx eslint --init
npx eslint --init
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard',
'plugin:react/recommended' // 使用共享配置
],
parserOptions: {
ecmaVersion: 12
},
rules: {
// 'react/jsx-uses-react': 2, // 避免 React 引入不使用,JSX 编译后需要
// 'react/jsx-uses-vars': 2
},
// plugins: [
// 'react'
// ]
}
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard',
'plugin:react/recommended' // 使用共享配置
],
parserOptions: {
ecmaVersion: 12
},
rules: {
// 'react/jsx-uses-react': 2, // 避免 React 引入不使用,JSX 编译后需要
// 'react/jsx-uses-vars': 2
},
// plugins: [
// 'react'
// ]
}
npx webpack
npx webpack
现代化项目集成 ESLint
现代化项目基本都已经集成 ESLint,这里以 vue-cli 进行演示。
npm install @vue/cli -g
npm install @vue/cli -g
vue create vue-app-demo
// Lint on save:webpack 构建时校验,保存时校验
// Lint and fix on commit: 利用 git 钩子,提交代码前校验
vue create vue-app-demo
// Lint on save:webpack 构建时校验,保存时校验
// Lint and fix on commit: 利用 git 钩子,提交代码前校验
ESLint 检查 TypeScript
typescript lint,你可能还使用过 ts-lint,不过目前官方已经不再维护 ts-lint,建议使用 ESLint 配合 typescript 插件进行代码校验。
npx eslint --int
// 选择 eslint
npx eslint --int
// 选择 eslint
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard'
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 12
},
plugins: [
'@typescript-eslint'
],
rules: {
}
}
module.exports = {
env: {
browser: true,
es2020: true
},
extends: [
'standard'
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 12
},
plugins: [
'@typescript-eslint'
],
rules: {
}
}
Stylelint 使用
css lint
- 提供默认的代码检查规则
- 提供 CLI 工具,可以快速调用
- 可以通过插件支持 Sass、Less、Postcss
- 支持 Gulp 或 webpack 集成
npm install stylelint -D
npm install stylelint-config-standard -D
npm install stylelint-config-sass-guidelines -D
npm install stylelint -D
npm install stylelint-config-standard -D
npm install stylelint-config-sass-guidelines -D
.stylelintrc.js
module.exports = {
extends: [
'stylelint-config-standard',
'stylelint-config-sass-guidelines'
]
}
module.exports = {
extends: [
'stylelint-config-standard',
'stylelint-config-sass-guidelines'
]
}
npx stylelint ./index.css
npx stylelint ./index.sass
npx stylelint ./index.css
npx stylelint ./index.sass
Prettier 使用
近两年,使用频率特别高的一款通用的、前端代码格式化工具。
它的功能很强大,几乎可以完成所有类型代码文件的格式化工作,我们可以使用它完成代码的自动格式化,还可以针对 Markdown 这一类的文档进行格式化操作。通过 Prettier,我们可以很容易的落实前端的规范化标准。
css
npm i prettier -D
npm i prettier -D
npx prettier ./style.css
npx prettier ./style.css
默认情况下会把格式化之后的代码输出到控制台中,如果想将格式化后的代码覆盖到源文件中
npx prettier ./style.css --write
npx prettier ./style.css --write
所有文件
npx prettier . --write
npx prettier . --write
不要过于依赖工具写出格式良好的代码,我们应该严格遵守格式,这是作为开发者的基本素质。
Git Hooks 工具机制
通过 Git Hooks 在代码提交前强制 lint。
- Git Hook 也成称为 git 钩子,每个钩子都对应一个任务
- 通过 shell 脚本可以编写钩子任务触发时要具体执行的操作
.git/hooks/pre-commit
#!/bin/sh
echo "before commit"
#!/bin/sh
echo "before commit"
git commit -m "perf: test"
git commit -m "perf: test"
ESLint 结合 Git Hooks
很多前端开发者并不擅长使用 shell 脚本编写功能,我们可以使用 husky 实现 Git Hooks 的使用需求。
npm install husky -D
npm install husky -D
package.json
{
"scripts": {
"lint": "eslint index.js"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
}
}
{
"scripts": {
"lint": "eslint index.js"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
}
}
我们还可以使用 lint-stage 模块
npm install lint-staged -D
npm install lint-staged -D
package.json
{
"scripts": {
"lint": "lint-staged"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"lint-staged": {
"*.json": [
"eslint",
'git add'
]
}
}
{
"scripts": {
"lint": "lint-staged"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"lint-staged": {
"*.json": [
"eslint",
'git add'
]
}
}
推荐使用 husky 配合 lint-staged,可以在 commit 之前验证代码,还可以在验证前后完后其他的操作。
git commit -m 'perf: test'
git commit -m 'perf: test'