赞
踩
vue3+vite+ts+eslint+prettier+stylelint+husky+lint-staged+commitlint+commitizen+cz-git
工作当中我我们可以不搭建,可以直接用开源的架子,如vben等,但是我们一定要知道是如何搭建,当然一个好用的工程化项目还需要很多细节的配置,学习一下应付面试也是可以的。
vscode
eslint
Prettier - Code formatter
Stylelint
Vue - Official
// 关闭IDE自带的样式验证 "css.validate": false, "less.validate": false, "scss.validate": false, // 指定stylelint生效的文件类型(尤其是vue文件) "stylelint.validate": ["css", "postcss", "scss", "vue"], // 启用eslint的格式化能力 "eslint.format.enable": true, // eslint 会在检查出错误时,给出对应的文档链接地址 "eslint.codeAction.showDocumentation": { "enable": true }, // 指定 eslint 生效的文件类型(尤其是 vue 文件)。 "eslint.probe": ["javascript", "typescript", "vue"], // 指定 eslint 的工作区,使每个子模块下的 .eslintignore 文件都能对当前目录生效。 "eslint.workingDirectories": [{ "mode": "auto" }], // 设置默认格式化工具为 Prettier "editor.defaultFormatter": "esbenp.prettier-vscode", // 默认禁用自动格式化(手动格式化快捷键:Shift + Alt + F) "editor.formatOnSave": true, "editor.formatOnPaste": true, // 启用自动代码修复功能,保存时触发 eslint 和 stylelint 的自动修复。 "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit", "source.fixAll.stylelint": "explicit" }, // json、yaml 等配置文件保存时自动格式化 "[json]": { "editor.formatOnSave": true }, "[jsonc]": { "editor.formatOnSave": true }, "[yaml]": { "editor.formatOnSave": true }, "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[ignore]": { "editor.defaultFormatter": "foxundermoon.shell-format" }, "[shellscript]": { "editor.defaultFormatter": "foxundermoon.shell-format" }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }
默认已经配置好pnpm
,vite
等环境。
pnpm create vite my-vue-app --template vue-ts
创建完的项目目录如下:
vite创建的项目给提供了两个tsconfig文件,一个是tsconfig.json
,一个是tsconfig.node.json
为什么会有两个?这个就牵扯到了tsconfig的一个概念[项目引用](TypeScript 中文网: 文档 - 项目引用 (nodejs.cn)),vue3官方文档也有写到关于ts的配置
也就是说,要想我们的tsconfig配置更加灵活,我们一般会将整个工程划分为多个ts project
tsconfig.base.json
基础的配置,供其他配置文件继承tsconfig.app.json
处理src目录下的源码文件,里面会有浏览器环境下也有的一些apitsconfig.node.json
处理node环境下执行的脚本,如vite.config.ts
tsconfig.eslint.json
处理eslint关于ts解析的配置tsconfig.json
通过references
聚合所有的配置,然后给IDE使用,每个被聚合的文件要加compilerOptions.composite = true
属性,才会被聚合在一起新建相关文件,这个时候我们的项目目录如下:
{ "compilerOptions": { "rootDir": ".", "baseUrl": ".", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "skipLibCheck": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "preserve", "jsxImportSource": "vue", /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true } }
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"composite": true,
// 增加了浏览器特有的dom相关api
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"types": ["node"],
"jsx": "preserve",
"jsxImportSource": "vue"
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "types/*.d.ts"],
"exclude": ["node_modules/*", "**/__tests__/**/*", "**/*.js", "dist/*"]
}
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"composite": true,
// 处理node脚本相关,不会有dom相关api
"lib": ["ESNext"],
"types": ["node"],
"allowJs": true
},
"include": ["vite.config.ts"]
}
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"noEmit": true
},
"include": ["**/*", "**/.*.*"],
"exclude": ["dist/*", "node_modules/*"]
}
{
"files": [],
"references": [{"path": "./tsconfig.app.json"},{ "path": "./tsconfig.node.json" }]
}
配置完之后我们发现tsconfig.node.json
有标红,这个时候我们下载@types/node
这个包即可
pnpm i -D @types/node
我们如果想要查看实际的编译选项或者包含的文件,我我们可以通过如下命令:
npx tsc -p tsconfig.aoo.json--showConfig
eslint使用8.x的版本,具体使用查看上面给出的文档
配置文件,本次搭建使用.eslintrc.cjs
因为package.json
里面type: module
扩展配置文件 extends
可以省略配置名称中的eslint-config-
前缀,如airbnb
会被解析为eslint-config-airbnb
配置插件 plugin
非范围包和范围包中都可以省略eslint-plugin-
前缀
非范围包
{
// ...
"plugins": [
"jquery", // means eslint-plugin-jquery
]
// ...
}
范围包
{
// ...
"plugins": [
"@jquery/jquery", // means @jquery/eslint-plugin-jquery
"@foobar" // means @foobar/eslint-plugin
]
// ...
}
配置规则 rules
off
或0
关闭规则warn
或1
启用并视作警告error
或2
启用并视作错误配置解析器 parser
默认情况下eslint会使用Espree
作为解析器,但是我们是vue项目会使用vue-eslint-parser
作为解析器
配置语言选项 env
env: {
browser: true,
es2022: true,
node: true,
}
指定解析器选项
{
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": "error"
}
}
忽略文件 使用.eslintignore
pnpm i -D eslint@8.57.0
pnpm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin vue-eslint-parser
pnpm i -D eslint-plugin-import eslint-plugin-vue eslint-config-airbnb-base eslint-config-airbnb-typescript
pnpm i -D eslint-plugin-prettier eslint-config-prettier
pnpm i -D eslint-define-config
@typescript-eslint/parser
eslint解析器,它允许eslint理解ts代码(eslint默认只能解析js代码)@typescript-eslint/eslint-plugin
eslint插件,包含了一些ts的设计规则,帮助开发者在开发的过程中避免一些常见的ts编程错误,并强制遵守一定的编码标准vue-eslint-parser
eslint解析器,用于解析.vue
文件中的<template>
标签内的内容,如指令,插值表达式等,需要配合eslint-plugin-vue
插件一起使用eslint-plugin-vue
是一个专为 Vue.js 设计的 ESLint 插件,它提供了一套规则来帮助开发者遵循 Vue.js 的最佳实践和风格指南。这个插件可以与 vue-eslint-parser
结合使用,以支持 .vue
文件的 <template>
部分的语法检查。eslint-plugin-import
是一个 ESLint 插件,它提供了一系列规则来帮助你避免常见的问题,并强制执行最佳实践,尤其是在处理模块导入时。这个插件特别有用,因为它可以帮助你检测未使用的导入、错误的导入语句、缺失的模块扩展名等问题。eslint-config-airbnb-base eslint-config-airbnb-typescript
这两个共享配置包需要用到eslint-plugin-import
eslint-config-airbnb-base eslint-config-airbnb-typescript
是两个不同的 ESLint 共享配置包,它们分别基于 Airbnb 的 JavaScript 和 TypeScript 编码规范。eslint-define-config
是一个用于创建 ESLint 配置的辅助工具,它提供了一个 defineConfig
函数,使得定义 ESLint 规则、插件和设置变得更加方便和类型安全。这个工具特别适合于需要在多个项目中重用相同 ESLint 配置的情况。eslint-config-prettier
它的主要作用是关闭 ESLint 中与 Prettier 冲突的规则。Prettier 是一个流行的代码格式化工具,它会根据一定的风格规则自动格式化代码。由于 ESLint 也包含了一些格式化相关的规则,这些规则可能与 Prettier 的格式化风格不一致,因此可能会导致冲突。eslint-config-prettier
就是为了解决这个问题而设计的。eslint-plugin-prettier
它将 Prettier 作为一个 ESLint 规则来运行,并将 Prettier 的输出与当前的代码进行比较// @ts-check const { defineConfig } = require('eslint-define-config'); const path = require('node:path'); /// <reference types="@eslint-types/typescript-eslint" /> module.exports = defineConfig({ // 告诉eslint这个就是搁那配置文件,不需要在去上层查找 root: true, // 配置全局环境api env: { browser: true, node: true, es2022: true, }, // 后续如果用到jquery等会用到 globals: { // $: "readonly", }, // 共享配置 extends: [ 'airbnb-base', // eslint-config-airbnb-base 'airbnb-typescript/base', // eslint-config-airbnb-typescript 'plugin:vue/vue3-recommended', // eslint-plugin-vue 具体为什么这么配置可以参考文档 'eslint-config-prettier', ], plugins: ['vue', 'prettier', '@typescript-eslint'], // 配置vue解析器 parser: 'vue-eslint-parser', // 指定ts的解析器 parserOptions: { parser: '@typescript-eslint/parser', // ts解析器里面的属性 project: path.resolve(__dirname, './tsconfig.eslint.json'), ecmaVersion: 13, sourceType: 'module', extraFileExtensions: ['.vue'], ecmaFeatures: { jsx: true, }, }, rules: { 'import/no-extraneous-dependencies': 'off', 'import/prefer-default-export': 'off', // vue 允许单单词组件名 'vue/multi-word-component-names': 'off', 'operator-linebreak': ['error', 'after'], 'class-methods-use-this': 'off', // 允许使用 ++ 'no-plusplus': 'off', 'no-spaced-func': 'off', // 换行符不作约束 'linebreak-style': 'off', }, overrides: [ { files: ['vite.config.ts'], rules: { 'no-console': 'off', }, }, ], });
.eslintignore
eslint默认忽略对.
开头文件的检查,对于一些其他配置文件,我们需要加!
反向声明忽略
dist node_modules public .husky .bin .vscode .idea *.sh *.md .DS_Store !.eslintrc.js !.stylelintrc.js !.prettierrc.js !.lintstagedrc.js !.commitlintrc.js
在package.json
中的scripts
中添加如下命令
# 检测文件
"lint:eslint": "eslint ."
# 检测文件并自动 fix
"fix:eslint": "eslint --ext .js,.jsx,.ts,.tsx,.vue --fix ./"
然后运行
说明我们的配置已经生效
是一个流行的代码格式化工具,它支持多种编程语言和文件类型,旨在提供一个统一的代码风格,以减少在代码审查过程中关于代码样式的讨论
pnpm i -D prettier
prettier.config.json
{ "printWidth": 80, "tabWidth": 2, "useTabs": false, "semi": true, "singleQuote": true, "quoteProps": "as-needed", "jsxSingleQuote": false, "trailingComma": "es5", "bracketSpacing": true, "jsxBracketSameLine": false, "bracketSameLine": false, "arrowParens": "avoid", "endOfLine": "auto", "embeddedLanguageFormatting": "auto", "vueIndentScriptAndStyle": true, "singleAttributePerLine": false, "htmlWhitespaceSensitivity": "css", "requirePragma": false, "insertPragma": false, "proseWrap": "preserve" }
.prettierignore
忽略文件.eslintrc-auto-import.json /types/components.d.ts /types/auto-import.d.ts node_modules .DS_Store dist dist-ssr .git .prettierignore .eslintignore .gitignore *.wasm *.txt *.png *.jpg *.jpeg *.gif *.bmp *.svg *.ttf *.ico *.lock *.sh *.md *.woff .browserslistrc *.local *debug.log* *error.log* *-lock.json .idea .vscode *.suo *.ntvs* *.njsproj *.sln
# 基础命令
"prettier": "prettier --no-editorconfig --config-precedence prefer-file \"**/*.{js,cjs,mjs,ts,cts,mts,json,jsonc,jsx,tsx,css,less,scss,styl,vue,html,md}\"",
# prettier 检测文件
"lint:prettier": "npm run prettier -- --check",
# prettier 检测文件并fix
"fix:prettier": "npm run prettier -- --write"
是一个强大的、现代化的 CSS 代码检查工具,它可以帮助开发者避免在样式表中出现错误,并保持一致的编码风格。
可以把下面的包以及版本好,拷贝到package.json的devDependencies
中,执行pnpm i
下载
"postcss": "^8.4.31",
"postcss-scss": "^4.0.9",
"postcss-html": "^1.5.0",
"sass": "^1.77.5",
"stylelint": "^15.10.3",
"stylelint-config-html": "^1.1.0",
"stylelint-config-prettier": "^9.0.5",
"stylelint-config-recommended-scss": "^13.0.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-config-standard-scss": "^11.0.0",
"stylelint-order": "^6.0.3",
"stylelint-scss": "^5.2.1"
stylelint.config.mjs
export default { plugins: ['stylelint-order'], extends: [ "stylelint-config-standard", // 配置 stylelint 拓展插件 "stylelint-config-html/vue", // 配置 vue 中 template 样式格式化 "stylelint-config-standard-scss", // 配置 stylelint scss 插件 "stylelint-config-recommended-vue/scss", // 配置 vue 中 scss 样式格式化 ], ignoreFiles: [ '**/*.js', '**/*.cjs', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml', 'node_modules/', 'dist/', 'public/', 'docs/', ], overrides: [ { files: ['**/*.(scss|css)'], customSyntax: 'postcss-scss', }, { files: ['**/*.(html|vue)'], customSyntax: 'postcss-html', }, ], rules: { "scss/at-import-partial-extension": null, 'scss/dollar-variable-pattern': null, // 解决类名不允许下划线 'scss/double-slash-comment-whitespace-inside': null,// 解决双斜杠注释后要有一个空格 'selector-class-pattern': null, 'block-no-empty': null, 'no-empty-source': null, 'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器 'selector-pseudo-element-no-unknown': [ true, { ignorePseudoElements: ['v-deep'], }, ], 'selector-pseudo-class-no-unknown': [ true, { ignorePseudoClasses: ['deep'], }, ], 'font-family-no-missing-generic-family-keyword': null, 'no-duplicate-selectors': null, 'selector-id-pattern': null, // 指定id选择器的模式 'custom-property-pattern': null, // 为自定义属性指定模式。 'no-invalid-double-slash-comments': null, // 禁止使用双斜杠注释(关闭) 'at-rule-no-unknown': [ true, { ignoreAtRules: ['mixin', 'if', 'else', 'include'], }, ], 'property-no-unknown': [ true, { ignoreProperties: ['line-clamp'], }, ], 'indentation': [2], 'order/properties-order': [ // 规则顺序 'position', 'content', 'top', 'right', 'bottom', 'left', 'float', 'display', 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left', 'margin-collapse', 'margin-top-collapse', 'margin-right-collapse', 'margin-bottom-collapse', 'margin-left-collapse', 'border', 'border-radius', 'outline', 'outline-offset', 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left', 'width', 'height', 'max-width', 'max-height', 'min-width', 'min-height', 'clip', 'font', 'font-family', 'font-size', 'font-smoothing', 'osx-font-smoothing', 'font-style', 'font-weight', 'line-height', 'letter-spacing', 'word-spacing', 'text-align', 'text-decoration', 'text-indent', 'text-overflow', 'text-rendering', 'text-size-adjust', 'text-shadow', 'text-transform', 'word-break', 'word-wrap', 'white-space', 'vertical-align', 'list-style', 'list-style-type', 'list-style-position', 'list-style-image', 'pointer-events', 'opacity', 'filter', 'visibility', 'size', 'transform', 'background', 'background-color', 'color', 'clear', 'cursor', 'overflow', 'overflow-x', 'overflow-y', 'z-index', ], }, }
.stylelintignore
文件不需要忽略的可以自行删除
.eslintrc-auto-import.json /types/components.d.ts /types/auto-import.d.ts node_modules .DS_Store dist dist-ssr .git .prettierignore .eslintignore .gitignore /bin /docs .husky Dockerfile *.wasm *.txt *.png *.jpg *.jpeg *.gif *.bmp *.svg *.ttf *.ico *.lock *.sh *.md *.woff .browserslistrcf *.local *debug.log* *error.log* *lock.json *.js *.jsx *.ts *.tsx .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw?
"lint:stylelint": "stylelint \"**/*.{css,scss,less,styl,postcss,vue}\"",
"fix:stylelint": "npm run lint:stylelint -- --fix"
husky是git的钩子函数,可以设置在git各个阶段触发,目前我们需要设置的两个钩子是:
pre-commit
commit-msg
git init
会生成一个隐藏的.git
文件夹
pnpm i -D husky
npx husky init
执行完npx husky init
之前要先配置好git,执行完,会生成一个.husky文件夹
init
命令简化了项目中的 husky 设置。它会在 .husky/
中创建 pre-commit
脚本,并更新 package.json
中的 prepare
脚本。随后可根据你的工作流进行修改。
lint-staged 是一个在 git add 到暂存区的文件运行 linters (ESLint/Prettier/StyleLint) 的工具,避免在 git commit 提交时在整个项目执行。lint-staged 可以让你当前的代码检查 只检查本次修改更新的代码,并在出现错误的时候,自动修复并且推送
pnpm i lint-staged -D
方式一:在package.json中添加
"lint-staged": { "*.{js,ts,vue}": [ "eslint --fix", "prettier --write", "git add" ], "*.{cjs,json}": [ "prettier --write" ], "*.{vue,html}": [ "eslint --fix", "prettier --write", "stylelint --fix" ], "*.{scss,css}": [ "stylelint --fix", "prettier --write" ], "*.md": [ "prettier --write" ] }
方式二: 新建一个lint-staged.config.cjs
文件,教程里面用的是这个方案
module.exports = {
"*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,vue}": ["eslint"],
"*.{css,scss,less,styl,postcss,vue,html}": ["stylelint"],
};
"lint:lint-staged": "lint-staged"
pre-commit
钩子函数配置#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint:lint-staged
结果如下,则配置生效,(前提要先git add .)
上面配置好了husky以及lint-staged之后,我们想要再提交commit的时候符合一定的标准如
npm install --save-dev @commitlint/config-conventional @commitlint/cli
commitlint.config.cjs
module.exports = { // 继承的规则 extends: ['@commitlint/config-conventional'], // @see: https://commitlint.js.org/#/reference-rules rules: { 'subject-case': [0], // subject大小写不做校验 // 类型枚举,git提交type必须是以下类型 'type-enum': [ // 当前验证的错误级别 2, // 在什么情况下进行验证,always表示一直进行验证 'always', [ 'feat', // 新增功能 'fix', // 修复缺陷 'docs', // 文档变更 'style', // 代码格式(不影响功能,例如空格、分号等格式修正) 'refactor', // 代码重构(不包括 bug 修复、功能新增) 'perf', // 性能优化 'test', // 添加疏漏测试或已有测试改动 'build', // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等) 'ci', // 修改 CI 配置、脚本 'revert', // 回滚 commit 'chore' // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例) ] ] } }
添加方式是husky9.x版本,husky那边要v8,v9更新的日志
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
运行完之后会在.husky中生成一个commit-msg
文件,或者手动添加,直接把下面的命令拷贝到commit-msg
当中
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
windows(win11)下面通过命令生成运行的时候有问题,所以直接手动添加内容
然后运行git commit -m '测试commit钩子'
说明我们的配置已经生效,可以看到提示我们sunject,type不能为空,修改一下git commit -m "feat: 规范的提交"
可以看到下面的图里没有了报错
正确的提交格式: <type>(<scope>): <subject>
但是我们希望再提交的时候不需要手写这些type,subject,怎么办?
commitizen
基于Node.js的 git commit 命令行工具,辅助生成标准化规范化的 commit messagecz-git
一款工程性更强,轻量级,高度自定义,标准输出格式的 commitizen 适配器# 全局安装
pnpm i -g commitizen
pnpm i -D cz-git
"config": {
"commitizen": {
"path": "node_modules/cz-git"
}
}
cz-git与commitlint进行联动给予校验信息,所以可以编写于commitlint.config.cjs
中
module.exports = {
// 继承的规则
extends: ["@commitlint/config-conventional"],
// @see: https://commitlint.js.org/#/reference-rules
rules: {
"subject-case": [0], // subject大小写不做校验
// 类型枚举,git提交type必须是以下类型
"type-enum": [
2,
"always",
[
"feat", // 新增功能
"fix", // 修复缺陷
"docs", // 文档变更
"style", // 代码格式(不影响功能,例如空格、分号等格式修正)
"refactor", // 代码重构(不包括 bug 修复、功能新增)
"perf", // 性能优化
"test", // 添加疏漏测试或已有测试改动
"build", // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)
"ci", // 修改 CI 配置、脚本
"revert", // 回滚 commit
"chore", // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)
],
],
},
prompt: {
messages: {
type: "选择你要提交的类型 :",
scope: "选择一个提交范围(可选):",
customScope: "请输入自定义的提交范围 :",
subject: "填写简短精炼的变更描述 :\n",
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
footerPrefixesSelect: "选择关联issue前缀(可选):",
customFooterPrefix: "输入自定义issue前缀 :",
footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
generatingByAI: "正在通过 AI 生成你的提交简短描述...",
generatedSelectByAI: "选择一个 AI 生成的简短描述:",
confirmCommit: "是否提交或修改commit ?",
},
// prettier-ignore
types: [
{ value: "feat", name: "特性: ✨ 新增功能", emoji: ":sparkles:" },
{ value: "fix", name: "修复: 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/972301
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。