React Vite 项目增加 eslint 和 prettier
Eslint 版本为 8.X
1. 安装 8.X 版本的 eslint
shell
pnpm i eslint@^8.57.0 -D
2. 安装其他包
shell
pnpm add -D eslint-plugin-import prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-prettier eslint-config-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
3. 初始化 eslint
shell
npx eslint --init
3.1. 选择 eslint 的校验模式
选择第三个
![](https://i-blog.csdnimg.cn/img_convert/415b9e38b0222df8eca5746d7b3c8049.png)
3.2. 选择项目类型
选择第一个 ESM 规范
![](https://i-blog.csdnimg.cn/img_convert/eeccd9f4ac0d0eaec56e0d1c23e0f2f9.png)
3.3. 选择项目框架
我们是 React,选择第一个
![](https://i-blog.csdnimg.cn/img_convert/580cecb692e4312396e11a8e74135ee9.png)
3.4. 是否使用 TS
项目中建议使用 TS
![](https://i-blog.csdnimg.cn/img_convert/e78e9f750387008e613f0d7a4e3099af.png)
3.5. 运行在哪?
我这个在浏览器
![](https://i-blog.csdnimg.cn/img_convert/c6f19bf9a7163362c8a9998e14cd183f.png)
3.6. 项目风格?
选择第二个
![](https://i-blog.csdnimg.cn/img_convert/f0fbbe522df582d63f5a4f2c60c1743a.png)
3.7. 选择 config 文件类型
我这边选择的是 JS
![](https://i-blog.csdnimg.cn/img_convert/40cac7c8b2e01b37764d36129c855df0.png)
3.8. 缩进
tabs
![](https://i-blog.csdnimg.cn/img_convert/f52f0683c7c50b2992725f1fb8941a11.png)
3.9. 单引号双引号
![](https://i-blog.csdnimg.cn/img_convert/5cb8d6871ba24b7be83833d907733a9d.png)
3.10. 行尾?
![](https://i-blog.csdnimg.cn/img_convert/211cfd9111073b7242687cb2df46b3c5.png)
3.11. 是否需要分号?
习惯了不要分号
![](https://i-blog.csdnimg.cn/img_convert/b9459372360a77c602ec77f64c17e448.png)
3.12. 添加依赖
YES
![](https://i-blog.csdnimg.cn/img_convert/4bcb0ee610cb2c2fcbf9b60345da7a1c.png)
3.13. 安装方式
pnpm 更快一些
![](https://i-blog.csdnimg.cn/img_convert/92d9a846f29ecfe0aa72f7f2e7de275d.png)
4. .eslintrc.cjs 文件
把默认生成的替换为以下内容
javascript
module.exports = {
root: true,
globals: {
chrome: true // 保留对 Chrome 扩展的支持
},
env: {
browser: true,
node: true,
es2021: true
},
parser: '@typescript-eslint/parser', // 使用 TypeScript 解析器
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true // 启用 JSX 支持
}
},
extends: [
'eslint:recommended', // 基本 ESLint 推荐配置
'plugin:react/recommended', // React 推荐配置
'plugin:react-hooks/recommended', // React Hooks 推荐配置
'plugin:@typescript-eslint/recommended', // TypeScript 推荐配置
'prettier', // 使用 Prettier
'plugin:prettier/recommended' // 确保 Prettier 配置生效
],
plugins: ['react', 'react-hooks', '@typescript-eslint', 'import'], // 加载相关插件
settings: {
react: {
version: 'detect' // 自动检测 React 版本
}
},
rules: {
'react/react-in-jsx-scope': 'off', // React 17+ 不需要显式导入 React
'react/prop-types': 'off', // 如果使用 TypeScript,则不需要 PropTypes
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-empty-interface': 0,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'@typescript-eslint/no-unused-expressions': 'off',
'semi': ['error', 'never'], // 禁止分号
'prettier/prettier': 'error', // 强制使用 Prettier 格式化
// 导入排序规则
'import/order': [
'error',
{
'newlines-between': 'never',
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
pathGroups: [
{
pattern: 'react',
group: 'external',
position: 'before'
},
{
pattern: 'react-dom',
group: 'external',
position: 'before'
},
{
pattern: '@/components/**',
group: 'internal',
position: 'before'
},
{
pattern: '@/utils/**',
group: 'internal',
position: 'before'
}
],
pathGroupsExcludedImportTypes: ['react', 'react-dom']
}
]
},
overrides: [
{
files: ['*.tsx', '*.jsx'], // 对 .tsx 和 .jsx 文件的特殊规则
rules: {
'react/prop-types': 'off' // TS 文件通常不需要 PropTypes
}
}
]
}
5. .eslintignore 文件
根据项目自己添加过滤文件
bash
node_modules/
dist/
build/
.vscode
.idea
.husky
*.json
*.config.js
6. .prettierrc.js 文件
javascript
/**
* @type {import('prettier').Options}
*/
export default {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
trailingComma: "none",
bracketSpacing: true,
bracketSameLine: true,
plugins: ["@ianvs/prettier-plugin-sort-imports"],
importOrder: [
"<BUILTIN_MODULES>", // Node.js built-in modules
"<THIRD_PARTY_MODULES>", // Imports not matched by other special words or groups.
"", // Empty line
"^@plasmo/(.*)$",
"",
"^@plasmohq/(.*)$",
"",
"^~(.*)$",
"",
"^[./]"
]
}
7. .prettierrc.json 文件
javascript
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
}
8. .prettierignore 文件
bash
# 忽略格式化文件 (根据项目需要自行添加)
node_modules/
dist/
build/
*.config.js
9. .vscode/extensions.json 文件
json
{
"recommendations": [
"Vue.vscode-typescript-vue-plugin",
"antfu.iconify", // iconify 图标显示
"antfu.unocss", // unocss 代码提示
"christian-kohler.path-intellisense", // 文件路径提示/补全
"dbaeumer.vscode-eslint", // eslint
"esbenp.prettier-vscode", // prettier
"eamodio.gitlens", // git
"editorconfig.editorconfig", // editorconfig
"mikestead.dotenv", // .env支持
"naumovs.color-highlight", // 颜色高亮
"steoates.autoimport",
"vue.volar" // vue3
]
}
10. .vscode/settings.json 文件
json
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"editor.fontLigatures": true,
"editor.formatOnSave": false,
"editor.guides.bracketPairs": "active",
"editor.quickSuggestions": {
"strings": true
},
"eslint.enable": true,
"editor.tabSize": 2,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"json",
"jsonc",
"json5",
"yaml",
"yml",
"markdown"
],
"files.associations": {
"*.env.*": "dotenv"
},
"files.eol": "\n",
"path-intellisense.mappings": {
"@": "${workspaceFolder}/src",
"~@": "${workspaceFolder}/src"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "Vue.volar"
}
}