前言
搭建一次前端工程可以用好久,但是每次搭建前端工程都要找各种资料从头开始,特别费力气,所以借着本次又搭建了一次工程的契机把自己的各种操作做个记录。
初始化
npm create vite
创建新项目,选择react+ts模板即可。
Eslint配置
eslint.config.js
整体配置如下:
import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from 'typescript-eslint';
import sonarjs from 'eslint-plugin-sonarjs';
import ImportPlugin from 'eslint-plugin-import';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import react from 'eslint-plugin-react';
import unicorn from 'eslint-plugin-unicorn';
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
import: ImportPlugin,
react,
sonarjs,
unicorn
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true }
],
'react/self-closing-comp': [
'error',
{
component: true,
html: true
}
],
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'all',
argsIgnorePattern: '^_',
caughtErrors: 'all',
caughtErrorsIgnorePattern: '^_',
destructuredArrayIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true
}
],
// 默认文件名规则为小驼峰
'unicorn/filename-case': [
'error',
{
cases: {
camelCase: true,
pascalCase: true
},
ignore: ['vite-env.d.ts']
}
],
'sonarjs/no-identical-functions': 'error',
'max-params': ['error', 5], // 规定函数的参数数量不能超过5个
'max-depth': ['error', 3], // 限制嵌套深度为 3
complexity: ['error', { max: 5 }], // 限制函数的复杂度为 5
'max-lines': ['error', { max: 800 }], // 规定文件的行数不能超过800行
'max-len': [
'error',
{
code: 300, // 规定一行代码的长度不能超过300个字符
ignoreComments: true, // 忽略注释的长度
ignoreUrls: true // 忽略URL的长度
}
],
// 分号
semi: ['error', 'always'],
'@typescript-eslint/naming-convention': [
'error',
// interface 大驼峰
{
selector: 'interface',
format: ['PascalCase']
},
// class 大驼峰
{
selector: 'class',
format: ['PascalCase']
},
// 枚举大驼峰
{
selector: 'enum',
format: ['PascalCase']
},
// 枚举值命名使用大写+下划线
{
selector: 'enumMember',
format: ['UPPER_CASE']
},
// 变量允许大小驼峰和纯大写
{
selector: 'variable',
format: ['camelCase', 'UPPER_CASE', 'PascalCase'],
leadingUnderscore: 'allow' // 允许前导下划线
},
// 函数允许大小驼峰
{
selector: 'function',
format: ['camelCase', 'PascalCase']
},
// 允许参数名使用小驼峰
{
selector: 'parameter',
format: ['camelCase', 'PascalCase'],
leadingUnderscore: 'allow' // 允许前导下划线
},
// 允许类成员变量使用小驼峰和全大写+下划线
{
selector: 'classProperty',
format: ['camelCase', 'UPPER_CASE', 'PascalCase']
}
],
'no-magic-numbers': [
'warn', // 仅提示警告
{
ignore: [0, 1, -1], // 忽略常见数值
ignoreArrayIndexes: true, // 忽略数组索引
enforceConst: true, // 强制要求将魔法值定义为常量
detectObjects: false, // 不检查对象属性中的数字
ignoreDefaultValues: true, // 忽略函数参数默认值中的魔法值
ignoreClassFieldInitialValues: true // 忽略class里的初始值
}
],
// 导入模块的顺序
'import/order': [
'error',
{
// 对导入模块进行分组,分组排序规则如下
groups: [
'builtin', // 内置模块
'external', // 外部模块
'parent', // 父节点依赖
'sibling', // 兄弟依赖
'internal', // 内部引用
'index', // index文件
'type', //类型文件
'unknown' // 未知依赖
],
// 是否开启独特组,用于区分自定义规则分组和其他规则分组
distinctGroup: true,
// 每个分组之间换行
'newlines-between': 'always',
// 相同分组排列规则 按字母升序排序
alphabetize: { order: 'asc', caseInsensitive: true }
}
]
}
},
eslintPluginPrettierRecommended
);
要点说明:
使用sonarjs插件来控制功能相同的函数
使用了import插件的order规则,配置导入顺序
@typescript-eslint/no-unused-vars限制未使用的变量,放行
_
符号react/self-closing-comp自闭和插件,用于使用eslint --fix的时候能够自动修复标签闭合
@typescript-eslint/naming-convention配置了一些书写习惯,具体的配置可以参考注释
no-magic-numbers限制魔法值的使用
eslintPluginPrettierRecommended,整合prettier与eslint。使用格式化修复的时候直接使用eslint --fix修复即可,这样可以防止与prettier冲突
添加工程指令
"lint": "eslint .",
"lint:fix": "eslint --fix .",
Prettier
在.prettierrc.cjs
中配置prettier
配置如下:
module.exports = {
printWidth: 80, // 定义每行代码的最大长度为80个字符,有助于提高代码的可读性
tabWidth: 2, // 设置缩进为2个空格,使代码结构清晰
semi: true, // 要求在语句末尾添加分号,避免JavaScript的自动分号插入(ASI)可能导致的问题
singleQuote: true, // 使用单引号,使代码风格更统一
trailingComma: 'none', // 在多行结构(如数组和对象)的最后一个元素后面添加逗号,有助于版本控制系统的diff更清晰
bracketSpacing: true, // 在对象的括号之间添加空格,提高代码的可读性
jsxBracketSameLine: true, // 将多行JSX元素的关闭标签放在最后一行的末尾,使代码风格更统一
proseWrap: 'preserve', // 当超出print width时,不对markdown文本进行换行,使得markdown文本的格式更一致
arrowParens: 'always', // 在单参数箭头函数中始终包含括号,避免添加或删除参数时需要修改箭头函数的问题
closeEmptyJsxElements: true, // 自动关闭空的JSX元素,使代码看起来更整洁
closeEmptyJsxTags: true, // 自动关闭空的JSX标签,使代码看起来更整洁
jsxSelfClosing: true, // 自动关闭JSX标签,使代码看起来更整洁
endOfLine: 'lf' // 使用LF作为换行符,避免不同操作系统下换行符不一致的问题
};
EditorConfig
.editorconfig
是对编辑器的配置,而prettier是对代码格式的限制。在
# EditorConfig 文件示例
# 表示这是项目根目录下的顶级 .editorconfig 文件,编辑器在查找配置时会停止向上查找
root = true
# 匹配所有文件
[*]
# 使用 UTF-8 编码
charset = utf-8
# 使用 Unix 风格的换行符
end_of_line = lf
# # 文件末尾会插入一个空行
# insert_final_newline = true
# 使用空格缩进符
indent_style = space
# 缩进大小为 2
indent_size = 2
Commitlint
commitlint.config.js配置commit message限制。
提交的message需要满足<type>(<scope>): <subject>
例如:
feat(login): add password reset functionality
fix(api): handle null response in getUser endpoint
docs(readme): update installation instructions
chore: update eslint configuration
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'subject-case': [0],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'docs',
'style',
'refactor',
'perf',
'test',
'build',
'ci',
'chore',
'revert',
'types',
'release'
]
]
}
};
StyleLint
配置对于样式文件的限制。
安装stylelint和相关插件
pnpm add stylelint stylelint-config-recommended-less stylelint-config-standard stylelint-less stylelint-order stylelint-prettier stylelint-selector-bem-pattern
.stylelintrc.cjs中配置
module.exports = {
root: true,
/* 继承其他规则, 用来扩展配置 */
extends: [
'stylelint-config-standard',
'stylelint-config-recommended-less',
'stylelint-prettier/recommended'
],
/* 排序和bem规则插件 */
plugins: [
'stylelint-order',
'stylelint-selector-bem-pattern',
'stylelint-prettier'
],
/* 忽略文件 */
ignoreFiles: [
'**/*.js',
'**/*.jsx',
'**/*.tsx',
'**/*.t
启用了bem规则,并且配置了命名遵守bem规则
配置了样式的排序顺序
添加工程指令
"stylelint": "stylelint 'src/**/*.{css,less}'",
"stylelint:fix": "stylelint --fix 'src/**/*.{css,less}'",
Husky配置
安装husky
pnpm add husky -D
添加npm的生命周期脚本
prepare会在会在pnpm install前运行,husky会往.git/hooks目录下面添加相关的钩子
// ...
"scripts": {
// ...
"prepare": "husky"
},
// ...
初始化husky
pnpm exec husky init
LintStaged
安装lint-staged
pnpm add lint-staged -D
这是一个用于检查git暂存区文件的工具,防止每次lint时扫描所有工程文件,提高效率。
在husky生成的.husky目录下的pre-commit写入pnpm run lint-staged --allow-empty
接着到package.json配置lint-stage的操作, 对于代码片段我们使用eslint修复它们,对于样式文件我们使用stylelint来修复:
{
// ...
"lint-staged": {
"*.{js,ts,jsx,tsx}": [
"eslint --fix"
],
"*.{less,css}": [
"stylelint --fix --allow-empty-input"
]
//...
},
}
.vscode目录配置
在工程目录下新建.vscode目录
新建extensions.json,写入这个项目建议使用的插件
{
"recommendations": [
"dbaeumer.vscode-eslint", //eslint
"esbenp.prettier-vscode", // prettier
"stylelint.vscode-stylelint", // stylelint
"editorconfig.editorconfig", // editorconfig
"christian-kohler.path-intellisense", // 文件路径智能提示
"kushagra-aa.wrap-it", // 标签快速包裹
"aaron-bond.better-comments", // 更好的代码注释插件
"streetsidesoftware.code-spell-checker" // 拼写检查
]
}
新建settings.json写入与当前工程相关的vscode配置
{
"editor.codeActionsOnSave": { //保存时的操作
"source.fixAll.eslint": "always", // 保存时总是修复eslint
"source.fixAll.stylelint": "explicit" // 显式触发修复,也就是手动触发修复
},
"editor.formatOnSave": true, // 保存时格式化代码
"editor.defaultFormatter": "esbenp.prettier-vscode", // 默认的格式化工具
"stylelint.enable": true, // 启动stylelint插件
"stylelint.validate": ["css", "less", "html"] // stylelint检查的文件类型
}
还可以再.vscode里写入一些像目录常用的代码片段,比如新建一个typescript.code-snippets,我们添加一个新增zuztand store的代码片段:
// typescript 代码片段
{
"Create Zustand Store": {
"prefix": "zus",
"body": [
"import { create } from 'zustand';",
"",
"interface ${TM_FILENAME_BASE/^(use)(.*)/$2/}State {",
" count: number;",
" setCount: (count: number) => void;",
"}",
"",
"const use${TM_FILENAME_BASE/^(use)(.*)/$2/}Store = create<${TM_FILENAME_BASE/^(use)(.*)/$2/}State>((set) => ({",
" count: 0,",
" setCount: (count) => set({ count })",
"}));",
"",
"export default use${TM_FILENAME_BASE/^(use)(.*)/$2/}Store;",
""
],
"description": "创建一个 Zustand Store 模板"
}
}
附录
参考文档:
react+vite6+ts+prettier+stylelint+husky+Lint-staged+Commitlint(2025版✨)
评论区