项目用到的技术点: vue3.2 pnpm vite typescript pinia
一. 项目创建
执行 pnpm create vite 创建项目
pnpm create vite
Project name: basic-project
Select a framework: Vue
Select a variant: TypeScript
然后把项目跑起来
pnpm install
pnpm dev
好了,现在一个基础的项目已经完成了
二. ESLint 配置
安装 ESLint | 文件检查依赖 vue 解析器 vue-eslint-parser | 用于检查 vue 文件规范的 eslint-plugin-vue
pnpm add eslint vue-eslint-parser eslint-plugin-vue -D
在根目录下创建 .eslintrc.js 用于配置 ESlint
module.exports = {
// ↓此项是用来告诉eslint找当前配置文件不能往父级查找
root: true,
// ↓指定你想启用的环境
env: {
browser: true,
node: true,
es6: true,
},
// ↓设置解析器
parser: 'vue-eslint-parser',
// ↓解析器选项
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true,
},
},
// ↓扩展项
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
// ↓自定义规则配置
rules: {
'vue/script-setup-uses-vars': 'error',
// ↓禁止使用@ts-ignore来消除ESLint检查
'@typescript-eslint/ban-ts-ignore': 'off',
// ↓在函数和类方法上需要显式的返回类型
'@typescript-eslint/explicit-function-return-type': 'off',
// ↓禁止使用any类型
'@typescript-eslint/no-explicit-any': 'off',
// ↓除导入语句外,禁止使用require语句
'@typescript-eslint/no-var-requires': 'off',
// ↓禁止使用空函数
'@typescript-eslint/no-empty-function': 'off',
// ↓对自定义事件名称强制使用特定的大小写
'vue/custom-event-name-casing': 'off',
// ↓禁止定义前使用
'no-use-before-define': 'off',
// ↓在定义变量之前不允许使用变量
'@typescript-eslint/no-use-before-define': 'off',
// ↓禁止使用@ts-注解
'@typescript-eslint/ban-ts-comment': 'off',
// ↓禁止使用特定类型
'@typescript-eslint/ban-types': 'off',
// ↓禁止使用!后缀运算符进行非null断言
'@typescript-eslint/no-non-null-assertion': 'off',
// ↓在导出的函数和类的公共类方法上需要显式的返回值和参数类型
'@typescript-eslint/explicit-module-boundary-types': 'off',
// ↓禁止使用未声明的变量
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
// ↓在函数括号前需要或不允许有空格
'space-before-function-paren': 'off',
// ↓强制属性顺序
'vue/attributes-order': 'off',
// ↓强制每个组件应位于其自己的文件中
'vue/one-component-per-file': 'off',
// ↓在标签的右括号之前要求或不允许换行
'vue/html-closing-bracket-newline': 'off',
// ↓强制每行的最大属性数
'vue/max-attributes-per-line': 'off',
// ↓在多行元素的内容之前和之后需要换行
'vue/multiline-html-element-content-newline': 'off',
// ↓在单行元素的内容之前和之后需要换行
'vue/singleline-html-element-content-newline': 'off',
// ↓在模板中的自定义组件上实施属性命名样式
'vue/attribute-hyphenation': 'off',
// ↓需要 prop 的默认值
'vue/require-default-prop': 'off',
'vue/require-explicit-emits': 'off',
// ↓实施自我封闭的风格
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'never',
component: 'always',
},
svg: 'always',
math: 'always',
},
],
'vue/multi-word-component-names': 'off',
},
};
配置不需要 ESLint 校验的文件 根目录下新增 .eslintignore
`*.sh`
`node_modules`
`*.md`
`*.woff`
`*.ttf`
`.vscode`
`.idea`
`dist`
`/public`
`.husky`
`.local`
`/bin`
三. Editorconfig 编辑器统一规范
根目录下新增 .editorconfig 文件
`root = ``true`
`[*]`
`charset=utf-8`
`end_of_line=lf`
`insert_final_newline=``true`
`indent_style=space`
`indent_size=2`
`max_line_length = 100`
`[*.{yml,yaml,json}]`
`indent_style = space`
`indent_size = 2`
`[*.md]`
`trim_trailing_whitespace = ``false`
`[Makefile]`
`indent_style = tab`
四. TypeScript 规范
安装 TSLint
pnpm add @typescript-eslint/eslint-plugin @typescript-eslint/parser -D
根目录下修改 tsconfig.json 文件
{
"compilerOptions": {
// ↓指定ECMAScript目标版本,esnext为最新版本
"target": "esnext",
// ↓指定生成哪个模块系统代码,esnext为最新版本
"module": "esnext",
// ↓决定如何处理模块。
"moduleResolution": "node",
// ↓启用所有严格类型检查选项。
"strict": true,
"noLib": false,
// ↓禁止对同一个文件的不一致的引用。
"forceConsistentCasingInFileNames": true,
// ↓允许从没有设置默认导出的模块中默认导入。这并不影响代码的输出,仅为了类型检查。
"allowSyntheticDefaultImports": true,
// ↓禁用函数参数双向协变检查。
"strictFunctionTypes": false,
// ↓在 .tsx文件里支持JSX
"jsx": "preserve",
// ↓解析非相对模块名的基准目录。查看 模块解析文档了解详情。
"baseUrl": ".",
// ↓允许编译javascript文件。
"allowJs": true,
// ↓生成相应的 .map文件。
"sourceMap": true,
"esModuleInterop": true,
"resolveJsonModule": true,
// ↓若有未使用的局部变量则抛错。
"noUnusedLocals": true,
// ↓若有未使用的参数则抛错。
"noUnusedParameters": true,
// ↓启用实验性的ES装饰器。
"experimentalDecorators": true,
// ↓编译过程中需要引入的库文件的列表。
"lib": ["dom", "esnext"],
// ↓要包含的类型声明文件名列表。
"types": ["vite/client"],
// ↓要包含的类型声明文件路径列表。
"typeRoots": ["./node_modules/@types/", "./types"],
"incremental": true,
// ↓在表达式和声明上有隐含的 any类型时报错。
"noImplicitAny": false,
// ↓忽略所有的声明文件( *.d.ts)的类型检查。
"skipLibCheck": true,
"removeComments": true,
// ↓模块名到基于 baseUrl的路径映射的列表。查看 模块解析文档了解详情。
"paths": {
"/@/*": ["src/*"],
"/#/*": ["types/*"]
}
},
// ↓指定一个匹配列表(属于自动指定该路径下的所有ts相关文件)
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"vite.config.ts"
],
// 指定一个排除列表(include的反向操作)
"exclude": ["node_modules", "dist", "**/*.js"]
}
五. Prettier 代码格式化
安装 prettier
pnpm add prettier -D
prettier 和 ESLint 有冲突 安装 eslint-plugin-prettier | eslint-config-prettier 解决冲突 将 prettier 一些规则默认关闭
pnpm add eslint-plugin-prettier eslint-config-prettier -D
根目录下新建 prettier.config.js 文件用于配置 prettier
module.exports = {
printWidth: 100,
semi: true,
vueIndentScriptAndStyle: true,
singleQuote: true,
trailingComma: 'all',
proseWrap: 'never',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'auto',
};
根目录下新建 .prettierignore 文件用于配置忽略校验的文件
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
六. StyleLint css样式规范
安装 styleLint
- stylelint 是对我们编写的样式进行检查的插件。
- stylelint-config-standard 是 stylelint **``**扩展的检查标准库
- stylelint-config-prettier 用来解决 prettier 冲突
- stylelint-order 是检查样式编写顺序
- stylelint-config-recess-order 保存时自动修复
- stylelint-config-recommended 解决 stylelint 14 版本问题
- stylelint-config-recommended-vue 解决 stylelint 14 版本问题
- stylelint-config-recommended-less 解决 stylelint 14 版本问题
- stylelint-config-html 解决 stylelint 14 版本问题
- postcss 解析器 把 css 转换为 EsTree
- postcss-html
- postcss-less
pnpm add stylelint stylelint-config-standard stylelint-config-prettier stylelint-order stylelint-config-recommended stylelint-config-recommended-vue -D
pnpm add stylelint-config-recess-order stylelint-config-recommended-less stylelint-config-html postcss postcss-html postcss-less -D
在根目录下新建 stylelint.config.js 用于配置 styleLint
module.exports = {
root: true,
plugins: ['stylelint-order'],
extends: ['stylelint-config-standard', 'stylelint-config-prettier'],
customSyntax: 'postcss-html',
rules: {
'function-no-unknown': null,
'selector-class-pattern': null,
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global'],
},
],
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep'],
},
],
'at-rule-no-unknown': [
true,
{
ignoreAtRules: [
'tailwind',
'apply',
'variants',
'responsive',
'screen',
'function',
'if',
'each',
'include',
'mixin',
],
},
],
'no-empty-source': null,
'string-quotes': null,
'named-grid-areas-no-invalid': null,
'unicode-bom': 'never',
'no-descending-specificity': null,
'font-family-no-missing-generic-family-keyword': null,
'declaration-colon-space-after': 'always-single-line',
'declaration-colon-space-before': 'never',
// 'declaration-block-trailing-semicolon': 'always',
'rule-empty-line-before': [
'always',
{
ignore: ['after-comment', 'first-nested'],
},
],
'unit-no-unknown': [true, { ignoreUnits: ['rpx'] }],
'order/order': [
[
'dollar-variables',
'custom-properties',
'at-rules',
'declarations',
{
type: 'at-rule',
name: 'supports',
},
{
type: 'at-rule',
name: 'media',
},
'rules',
],
{ severity: 'warning' },
],
},
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'],
overrides: [
{
files: ['*.vue', '**/*.vue', '*.html', '**/*.html'],
extends: ['stylelint-config-recommended'],
rules: {
'keyframes-name-pattern': null,
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['deep', 'global'],
},
],
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'],
},
],
},
},
{
files: ['*.less', '**/*.less'],
customSyntax: 'postcss-less',
extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue'],
},
],
};