VsCode
基础设置
- 保存格式化:设置 → 搜索 Format On Save → 勾选
- Tab Size:设为
2
EditorConfig
安装扩展 EditorConfig for VS Code;部分 IDE(如 WebStorm)内置支持,其余需独立安装。
文档:editorconfig.org
VS Code 支持的属性
| 配置 | 描述 |
|---|---|
| [*] | 匹配全部文件,匹配除 / 路径分隔符外的任意字符串 |
| charset | latin1、utf-8、utf-8-bom、utf-16be、utf-16le(不推荐 utf-8-bom) |
| end_of_line | lf、cr、crlf |
| indent_size | 缩进列数;indent_style 为 tab 时用 tab_width |
| indent_style | space | tab |
| insert_final_newline | true 时文件以换行结尾 |
| trim_trailing_whitespace | 删除行首尾空格 |
换行符: lf(\n)、cr(\r)、crlf(\r\n)
根目录 .editorconfig:
# https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
.vscode/extensions.json:
{
"recommendations": ["editorconfig.editorconfig"]
}
Prettier
格式化代码,支持 json、js;ts 可用 cjs。本质将代码转为 AST 再格式化。
Playground:prettier.io/playground/
安装
yarn add --dev --exact prettier
npm i prettier -D
配置文件格式
优先级从高到低:.prettierrc.js / .prettierrc.cjs、.prettierrc.json、.prettierrc.yaml / .yml、.prettierrc.toml、package.json 的 prettier 字段。
项目示例 .prettierrc.cjs
module.exports = {
printWidth: 120,
useTabs: false,
tabWidth: 2,
semi: false,
singleQuote: true,
jsxSingleQuote: true,
arrowParens: "avoid",
bracketSpacing: true,
trailingComma: "none",
jsxBracketSameLine: false,
};
配置项详解
缩进与宽度
| 配置项 | 默认值 | 说明 |
|---|---|---|
| printWidth | 80 | 每行最大字符数,超过则换行 |
| tabWidth | 2 | 每个缩进级别的空格数 |
| useTabs | false | 是否用 Tab 代替空格 |
分号
| 配置项 | 默认值 | 说明 |
|---|---|---|
| semi | true | 是否在语句末尾添加分号 |
引号
| 配置项 | 默认值 | 说明 |
|---|---|---|
| singleQuote | false | 是否使用单引号(JSX 默认仍可能用双引号,见 jsxSingleQuote) |
| jsxSingleQuote | false | JSX 中是否使用单引号 |
| quoteProps | "as-needed" | 对象属性引号:as-needed / consistent / preserve |
尾随逗号 trailingComma
| 值 | 说明 |
|---|---|
| none | 不加 |
| es5 | 对象、数组等 ES5 有效位置 |
| all | 含函数参数、调用等 |
括号
| 配置项 | 默认值 | 说明 |
|---|---|---|
| bracketSpacing | true | { foo: bar } vs {foo: bar} |
| bracketSameLine | false | 多行 JSX/HTML 的 > 是否放在最后一行末尾 |
| arrowParens | "always" | always 总加括号;avoid 单参数可省略 |
jsxBracketSameLine已废弃,Prettier 2.4+ 使用bracketSameLine。
| 配置项 | 默认值 | 说明 |
|---|---|---|
| singleAttributePerLine | false | JSX/HTML/TSX 是否每属性一行 |
换行符与文件
| 配置项 | 默认值 | 说明 |
|---|---|---|
| endOfLine | "lf" | lf / crlf / cr / auto |
| insertPragma | false | 是否在文件顶插入 @format |
| requirePragma | false | 是否仅格式化带 @format 的文件 |
| embeddedLanguageFormatting | "auto" | auto / off |
HTML / JSX
| 配置项 | 默认值 | 说明 |
|---|---|---|
| htmlWhitespaceSensitivity | "css" | css / strict / ignore |
| vueIndentScriptAndStyle | false | Vue 中是否缩进 script/style 内容 |
其它格式
| 配置项 | 默认值 | 说明 |
|---|---|---|
| proseWrap | "preserve" | Markdown:always / never / preserve |
| parser | 自动推断 | 如 typescript、json、css |
Overrides 示例
module.exports = {
singleQuote: true,
overrides: [
{ files: "*.json", options: { parser: "json", tabWidth: 2 } },
{ files: ["*.yml", "*.yaml"], options: { tabWidth: 2, singleQuote: false } },
],
};
文档示例(另一套取值,作对照)
module.exports = {
printWidth: 120,
tabWidth: 2,
semi: true,
singleQuote: true,
jsxBracketSameLine: true,
bracketSameLine: true,
bracketSpacing: false,
arrowParens: "avoid",
trailingComma: "es5",
};
.prettierignore
语法同 .gitignore。项目示例:
node_modules/**
dist/**
public/**
doc/**
*.md
coverage/**
常见忽略:node_modules、dist、build、coverage、package-lock.json、*.min.js
CLI 与 scripts
npx prettier --check .
npx prettier --write .
npx prettier --write "src/**/*.{ts,tsx,js,jsx,json,css,less,md}"
package.json:
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,scss,stylus,html,md}\""
--write:写回文件--loglevel warn:仅警告级日志
{
"scripts": {
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,less,md}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,less,md}\""
}
}
VS Code
根目录 .vscode/settings.json。prettier.requireConfig: true 时须有 Prettier 配置文件,否则保存可能不格式化;false 时无配置文件也可用扩展默认(有配置文件则以文件为准)。
{
"search.exclude": {
"/node_modules": true,
"dist": true,
"pnpm-lock.yaml": true
},
"files.autoSave": "onFocusChange",
"editor.formatOnSave": true,
"editor.formatOnType": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[javascriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[json]": { "editor.defaultFormatter": "vscode.json-language-features" },
"[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
"javascript.validate.enable": false
}
插件:editor.defaultFormatter": "esbenp.prettier-vscode"、editor.formatOnSave": true(与上可合并使用)。
ESLint
识别并报告 ECMAScript/JavaScript 模式,使代码一致并减少错误。
文档:eslint.org/docs/latest…
Node:^12.22.0、^14.17.0 或 >=16.0.0(v9 见下)
| 依赖 | 描述 |
|---|---|
| eslint-config-standard | Standard 预设 |
| eslint-config-airbnb | Airbnb 规范 |
| @typescript-eslint/parser | TS 解析器 |
| @typescript-eslint/eslint-plugin | TS 规则 |
| eslint-plugin-react | React 规则 |
| eslint-plugin-import | import 规则 |
standard / airbnb 二选一安装:
pnpm add eslint eslint-config-standard eslint-plugin-import -D
React:
pnpm add eslint-plugin-react-hooks eslint-plugin-react -D
TypeScript:
pnpm add @typescript-eslint/eslint-plugin @typescript-eslint/parser -D
.eslintrc.js 示例:
module.exports = {
env: { browser: true, es2021: true, node: true },
extends: [
"standard",
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:react-hooks/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaFeatures: { jsx: true },
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["react", "@typescript-eslint", "react-hooks", "import"],
rules: {},
};
其它插件
- eslint-plugin-jsx-a11y — JSX 可访问性
- eslint-plugin-react-refresh — refresh() 相关,加快 HMR
- eslint-plugin-promise — Promise 用法
- eslint-plugin-node — Node 环境陷阱与安全 API
plugins: [
"jsx-a11y",
"react-refresh",
"promise",
"node",
],
eslint-friendly-formatter — 自定义报告样式:
module.exports = {
formatter: require("eslint-friendly-formatter"),
};
eslint-import-resolver-alias — 路径别名:
module.exports = {
settings: { "import/resolver": { alias: true } },
};
ESLint 配置字段说明
root — true 为本文件根配置,不再向父目录查找(monorepo 子包常用)。
parserOptions — 传给解析器:sourceType: "module" 按 ES 模块解析;旧项目可能用 babel-eslint,新项目常见 @babel/eslint-parser(与 Babel 版本对齐)。
env — 运行环境全局,如 browser、es6 / es2021。
extends — 继承规则集,如 eslint:recommended、plugin:vue/recommended(需 eslint-plugin-vue)。
rules — 覆盖 extends;off / warn / error(或 0 / 1 / 2)。
文档若仍写
babel-eslint,新工程可迁@babel/eslint-parser。
常用 rules 备忘
严重级别:0/off 关闭,1/warn 警告,2/error 错误。
环境与调试(随构建环境切换)
no-console:生产 错误,开发关闭no-debugger:同上
Vue(eslint-plugin-vue)
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| vue/attribute-hyphenation | 关闭 | 不强制模板属性 kebab-case |
| vue/max-attributes-per-line | 错误 | 单行最多 10 个属性;多行每行 1 个 |
| vue/singleline-html-element-content-newline | 关闭 | 不强制单行标签内换行 |
| vue/multiline-html-element-content-newline | 关闭 | 不强制多行标签内换行 |
| vue/html-closing-bracket-newline | 关闭 | 不强制闭合 > 单独换行 |
| vue/no-v-html | 关闭 | 允许 v-html(注意 XSS) |
| vue/html-self-closing | 关闭 | 不强制自闭合 |
| vue/require-default-prop | 关闭 | 不强制 prop 默认值 |
| vue/require-prop-types | 关闭 | 不强制 prop 类型 |
类、函数、this 与构造
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| accessor-pairs | 错误 | getter/setter 成对 |
| constructor-super | 错误 | 派生类须先 super |
| consistent-this | 错误,别名 that | 统一 this 别名 |
| curly | 错误,multi-line | 多行或易歧义时须 {} |
| new-cap | 错误 | new 配大写构造;允许直接调大写函数 |
| new-parens | 错误 | new Foo() 须括号 |
| no-class-assign | 错误 | 禁止对类名再赋值 |
| no-const-assign | 错误 | 禁止对 const 再赋值 |
| no-dupe-class-members | 错误 | 禁止类成员重名 |
| no-dupe-args | 错误 | 禁止参数重名 |
| no-func-assign | 错误 | 禁止对函数声明再赋值 |
| no-inner-declarations | 错误,仅 functions | 禁止嵌套块内 function 声明 |
| no-new-symbol | 错误 | 禁止 new Symbol() |
| no-obj-calls | 错误 | 禁止把 Math/JSON/Reflect 当函数调 |
| no-useless-constructor | 错误 | 禁止空壳构造 |
| no-this-before-super | 错误 | super() 前禁止 this/super |
| wrap-iife | 错误,any | IIFE 须括号包裹 |
比较、控制流与异常
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| eqeqeq | 错误,always,null 忽略 | 用 === / !== |
| no-dupe-keys | 错误 | 对象禁止重复键 |
| no-duplicate-case | 错误 | switch 禁止重复 case |
| no-fallthrough | 错误 | case 贯穿须注释或改写 |
| no-self-compare | 错误 | 禁止 x === x |
| no-sequences | 错误 | 禁止逗号表达式副作用 |
| no-unmodified-loop-condition | 错误 | 循环条件变量须在循环内更新 |
| no-unneeded-ternary | 错误,defaultAssignment: false | 禁止可简化三元 |
| no-unreachable | 错误 | return/throw 后禁止死代码 |
| no-unsafe-finally | 错误 | finally 里禁止 return/throw 破坏完成 |
| no-throw-literal | 错误 | 禁止 throw 非 Error |
| valid-typeof | 错误 | typeof 与合法字符串比较 |
| use-isnan | 错误 | 用 Number.isNaN / isNaN |
| yoda | 错误,never | 禁止尤达条件 |
危险写法与全局污染
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| no-eval | 错误 | 禁止 eval |
| no-implied-eval | 错误 | 禁止 setTimeout(string) 等 |
| no-with | 错误 | 禁止 with |
| no-extend-native | 错误 | 禁止改内置原型 |
| no-native-reassign | 错误 | 禁止对只读全局再赋值 |
| no-new-wrappers | 错误 | 禁止 new String/Number/Boolean |
| no-iterator | 错误 | 禁止 iterator |
| no-labels | 错误,allowLoop/Switch: false | 限制 label |
| no-label-var | 错误 | label 勿与变量冲突 |
| no-lone-blocks | 错误 | 禁止无意义单独块 |
正则与字符串
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| no-control-regex | 关闭 | 关闭时不检查控制字符 |
| no-empty-character-class | 错误 | 禁止 [] 空类 |
| no-invalid-regexp | 错误 | RegExp 参数须合法 |
| no-regex-spaces | 错误 | 正则字面量禁止多空格 |
| no-useless-escape | 关闭 | 不报告多余转义 |
变量、require 与模块
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| no-delete-var | 错误 | 禁止 delete 变量 |
| no-redeclare | 错误 | 禁止同作用域重复声明 |
| no-undef | 错误 | 禁止未声明标识符 |
| no-undef-init | 错误 | 禁止 var x = undefined |
| no-unused-vars | 错误,vars: all,args: after-used | 未使用变量;参数从后往前算 |
| no-var | 错误 | 禁止 var |
| prefer-const | 错误 | 未再赋值 let 改 const |
| one-var | 错误,initialized: never | 已初始化变量分开声明 |
| global-require | 警告 | 倾向顶层 require |
| no-new-require | 错误 | 禁止 new require(...) |
| no-path-concat | 错误 | 路径用 path API |
| no-new-object | 错误 | 倾向 {} |
| no-array-constructor | 警告 | 倾向 [] |
赋值、返回与解构
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| no-return-assign | 错误,except-parens | return 右侧禁止易混赋值 |
| no-self-assign | 错误 | 禁止 a = a |
| no-ex-assign | 错误 | 禁止对 catch(e) 的 e 再赋值 |
| prefer-destructuring | 错误,object/array: false | 不强制解构 |
| no-empty-pattern | 错误 | 禁止空解构模式 |
其它逻辑与风格
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| camelcase | 错误,properties: always | 属性名驼峰 |
| dot-location | 错误,property | . 在下一行属性侧 |
| no-extra-boolean-cast | 错误 | 禁止冗余 !! |
| no-extra-parens | 错误,functions | 函数相关多余括号 |
| no-floating-decimal | 错误 | 禁止 .5、5. |
| no-octal | 错误 | 禁止八进制字面量 |
| no-octal-escape | 错误 | 禁止八进制转义 |
| no-sparse-arrays | 错误 | 禁止稀疏数组 |
| no-multi-str | 错误 | 禁止反斜杠续行多行字符串 |
| no-multiple-empty-lines | 错误,max: 1 | 连续空行最多 1 |
| no-trailing-spaces | 错误 | 行尾无空白 |
| eol-last | 错误 | 文件末尾换行 |
| no-mixed-spaces-and-tabs | 错误 | 勿混 tab 与空格 |
| no-multi-spaces | 错误 | 禁止无意义多空格 |
| no-irregular-whitespace | 错误 | 禁止非常规空白 |
| no-unexpected-multiline | 错误 | 避免 ASI 意外多行 |
| no-whitespace-before-property | 错误 | .prop 前无空格 |
| no-underscore-dangle | 错误 | 默认禁止首尾 _ |
| no-useless-call | 错误 | 禁止可普通调用的 call/apply |
| no-useless-computed-key | 错误 | 禁止可点访问的计算键 |
| generator-star-spacing | 错误 | function* 的 * 两侧空格 |
| yield-star-spacing | 错误,both | yield* 的 * 两侧空格 |
格式与空格(Stylistic)
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| arrow-spacing | 错误 | => 两侧空格 |
| block-spacing | 错误,always | 块内侧空格 |
| brace-style | 错误,1tbs | One True Brace Style |
| comma-dangle | 错误,never | 禁止尾随逗号 |
| comma-spacing | 错误 | 逗号前无、后有空格 |
| comma-style | 错误,last | 逗号在行尾 |
| indent | 错误,2 空格,SwitchCase: 2 | 缩进 |
| key-spacing | 错误 | 对象键值冒号空格 |
| keyword-spacing | 错误 | 关键字两侧空格 |
| object-curly-spacing | 错误,always | {} 内侧空格 |
| array-bracket-spacing | 错误,never | [] 内侧不空格 |
| quotes | 错误,单引号,avoidEscape | 默认单引号 |
| semi | 错误,never | 不使用分号 |
| semi-spacing | 错误 | 分号前后空格 |
| space-before-blocks | 错误,always | { 前空格 |
| space-before-function-paren | 错误,never | function( 前无空格 |
| space-in-parens | 错误,never | () 内侧不空格 |
| space-infix-ops | 错误 | 中缀运算符两侧空格 |
| space-unary-ops | 错误 | new/typeof 要空格;++ 不加 |
| spaced-comment | 错误,always | // /* 后须空格 |
| template-curly-spacing | 错误,never | ${} 内不空格 |
| operator-linebreak | 错误 | 默认行尾断行 |
| padded-blocks | 错误,never | 块内首尾不空行 |
其它
| 规则 | 级别与要点 | 说明 |
|---|---|---|
| radix | 错误 | parseInt 须写进制 |
迁回 .eslintrc.js 时可将「级别与要点」还原为数组;no-console / no-debugger 的环境判断须写在配置里而非静态表。
ESLint v9
Node >=18.18.0。
pnpm create @eslint/config@latest
初始化选项:语法检查 → ES modules → 选框架 → TypeScript Yes → Browser+Node → 配置格式 JavaScript → npm 安装 Yes。
与 Prettier 协作
| 包 | 作用 |
|---|---|
| eslint-config-prettier | 关闭与 Prettier 冲突的 ESLint 规则 |
| eslint-plugin-prettier | 将 Prettier 作为 ESLint 规则运行 |
pnpm install eslint-plugin-prettier eslint-config-prettier -D
npm i eslint-config-prettier -D
.eslintrc / .eslintrc.js:
module.exports = {
extends: [
"some-other-config",
"plugin:prettier/recommended", // 或仅 "prettier",须放在 extends 最后
],
};
.vscode/settings.json:
{
"eslint.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}
Git hooks(lint-staged + husky)
{
"lint-staged": {
"*.{ts,tsx,js,jsx,json,css,less,md}": ["prettier --write"]
}
}