Vue项目实战
- 项目搭建
- 初始化
- eslint+版本约束
- 版本约束
- eslint配置
- stylelint
- cspell
- cz-git
- husky
- 给拦截举个例子
- zx
项目搭建
node版本:20.11.1
pnpm版本:9.0.4
初始化
vue3最新的脚手架
pnpm create vite byelide-demo --template vue-ts
pnpm i
pnpm dev
改端口号:
vite.config.ts:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
server:{
port: 8888
}
})
eslint+版本约束
版本约束
package.json
{
"name": "byelide-demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"lint":"eslint --fix .",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "3.4.26"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",
"typescript": "5.4.5",
"vite": "5.2.10",
"vue-tsc": "2.0.15",
"eslint": "9.1.1"
}
}
pnpm lint
eslint配置
package.json加:
"eslint-plugin-vue":"9.25.0",
"vue-eslint-parser":"9.4.2"
eslint.config.js:
import pluginVue from 'eslint-plugin-vue';
import vueEslintParser from 'vue-eslint-parser'
export default [
{
files:["**/*,.{ts,tsx,vue}"],
rules: {
semi: "error",
"prefer-const": "error",
"no-console":'error'
}
}
];
再执行:
pnpm i
最终版本:
eslint.config.js:
import js from "@eslint/js";
import pluginVue from 'eslint-plugin-vue';
// importSort插件功能是:项目中引入插件的顺序必须先是官方,后是自己的插件
import importSort from 'eslint-plugin-simple-import-sort';
import vueEslintParser from 'vue-eslint-parser'
import globals from 'globals';
export default [
{
languageOptions:{
globals:{
...globals.browser,
computed:"readonly",
defineEmits:"readonly",
defineExpose:"readonly",
defineProps:"readonly",
onMounted:"readonly",
onUnmounted:"readonly",
reactive:"readonly",
ref:"readonly",
shallowReactive:"readonly",
shallowRef:"readonly",
toRef:"readonly",
toRefs:"readonly",
watch:"readonly",
watchEffect:"readonly"
}
}
},
{
files:["**/*,.{ts,tsx,vue}"],
ignores:[],
rules: {
...js.configs.recommended.rules,
...pluginVue.configs['flat/recommended'].rules,
"no-console":'error',
'no-debugger':"error",
"vue/valid-define-emits":"error",
"simple-import-sort/imports":"error",
"simple-import-sort/exports":"error"
},
languageOptions:{
parser: vueEslintParser,
parserOptions: {
ecmaFeatures:{
jsx:true
},
extraFileExtensions:[".vue"]
}
},
// eslint 9.x 版本的插件注册方式
plugins:{
vue:pluginVue,
"simple-import-sort":importSort
}
}
];
package.json
{
"name": "byelide-demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"lint":"eslint --fix .",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "3.4.26"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",
"typescript": "5.4.5",
"vite": "5.2.10",
"vue-tsc": "2.0.16",
"eslint": "9.1.1",
"@eslint/js":"9.1.1",
"eslint-plugin-vue":"9.25.0",
"vue-eslint-parser":"9.4.2",
"globals":"15.1.0",
"eslint-plugin-simple-import-sort": "12.1.0"
}
}
安装插件
pnpm i
校验正确:
pnpm lint
stylelint
package.json:
scripts加入:
"lint:style":"stylelint **/*.vue",
加依赖,devDependencies加
"stylelint": "16.4.0",
"stylelint-config-recommended-vue":"1.5.0"
package.json:
{
"name": "byelide-demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"lint":"eslint --fix .",
"lint:style":"stylelint **/*.vue",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "3.4.26"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",
"typescript": "5.4.5",
"vite": "5.2.10",
"vue-tsc": "2.0.16",
"eslint": "9.1.1",
"@eslint/js":"9.1.1",
"eslint-plugin-vue":"9.25.0",
"vue-eslint-parser":"9.4.2",
"globals":"15.1.0",
"eslint-plugin-simple-import-sort": "12.1.0",
"stylelint": "16.4.0",
"stylelint-config-recommended-vue":"1.5.0"
}
}
插件化机制
就是这里用的plugin的思路 本来eslint只是基础的架子,但是能实现那么强的校验的规则和逻辑,就是因为它能够支持你通过插件注册的形式把你外部的和把所有权交给开发者,让开发者编写对应的规则来增强功能,这就是插件化(微内核)的思路
stylelint.config.js:
/** @type {import('stylelint').Config} */
export default {
extends:['stylelint-config-recommended-vue'],
rules: {
"declaration-property-unit-allowed-list":{
"font-size":["px"] //font-size只能用px单位
},
"selector-disallowed-list":["/\\data-.+]/"] //不能使用data-xx形式
}
};
pnpm i
pnpm lint:style
cspell
package.json的scripts:
"spellcheck":"cspell lint --dot --gitignore --color --cache --show-suggestions \"src/**/*.@(html|js|cjs|mjs|ts|tsx|css|scss|md|vue)\"",
devDependencies加入:
"cspell":"8.7.0"
package.json:
{
"name": "byelide-demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"lint":"eslint --fix .",
"lint:style":"stylelint **/*.vue",
"spellcheck":"cspell lint --dot --gitignore --color --cache --show-suggestions \"src/**/*.@(html|js|cjs|mjs|ts|tsx|css|scss|md|vue)\"",
"build": "vue-tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"vue": "3.4.26"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",
"typescript": "5.4.5",
"vite": "5.2.10",
"vue-tsc": "2.0.16",
"eslint": "9.1.1",
"@eslint/js":"9.1.1",
"eslint-plugin-vue":"9.25.0",
"vue-eslint-parser":"9.4.2",
"globals":"15.1.0",
"eslint-plugin-simple-import-sort": "12.1.0",
"stylelint": "16.4.0",
"stylelint-config-recommended-vue":"1.5.0",
"cspell":"8.7.0"
}
}
cspell.json:
{
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
"version": "0.2",
"dictionaryDefinitions": [
{
"name": "customs-words",
"path": ".cspell/project-words.txt",
"addWords": true
}
],
"dictionaries": ["project-words"],
"ignorePaths": ["node_modules", "/project-words.txt"]
}
创建文件:
安装:
pnpm i
测试:
pnpm spellcheck
cz-git
package.json:
devDependencies中加:
"cz-git":"1.9.1",
"commitizen":"4.3.0"
package.json中加:
"config": {
"commitizen": {
"path": "node_modules/cz-git"
}
},
scripts中加:
"commit":"git-cz"
package.json:
{
"name": "byelide-demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"lint":"eslint --fix .",
"lint:style":"stylelint **/*.vue",
"spellcheck":"cspell lint --dot --gitignore --color --cache --show-suggestions \"src/**/*.@(html|js|cjs|mjs|ts|tsx|css|scss|md|vue)\"",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"commit":"git-cz"
},
"config": {
"commitizen": {
"path": "node_modules/cz-git"
}
},
"dependencies": {
"vue": "3.4.26"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",
"typescript": "5.4.5",
"vite": "5.2.10",
"vue-tsc": "2.0.16",
"eslint": "9.1.1",
"@eslint/js":"9.1.1",
"eslint-plugin-vue":"9.25.0",
"vue-eslint-parser":"9.4.2",
"globals":"15.1.0",
"eslint-plugin-simple-import-sort": "12.1.0",
"stylelint": "16.4.0",
"stylelint-config-recommended-vue":"1.5.0",
"cspell":"8.7.0",
"cz-git":"1.9.1",
"commitizen":"4.3.0"
}
}
pnpm i
git init
git add .
pnpm commit
创建commitlint.config.cjs文件:
中英对照配置
// .commitlintrc.js
/** @type {import('cz-git').UserConfig} */
module.exports = {
rules: {
// @see: https://commitlint.js.org/#/reference-rules
},
prompt: {
alias: { fd: 'docs: fix typos' },
messages: {
type: '选择你要提交的类型 :',
scope: '选择一个提交范围(可选):',
customScope: '请输入自定义的提交范围 :',
subject: '填写简短精炼的变更描述 :\n',
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
footerPrefixesSelect: '选择关联issue前缀(可选):',
customFooterPrefix: '输入自定义issue前缀 :',
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
confirmCommit: '是否提交或修改commit ?'
},
types: [
{ value: 'feat', name: 'feat: 新增功能 | A new feature' },
{ value: 'fix', name: 'fix: 修复缺陷 | A bug fix' },
{ value: 'docs', name: 'docs: 文档更新 | Documentation only changes' },
{ value: 'style', name: 'style: 代码格式 | Changes that do not affect the meaning of the code' },
{ value: 'refactor', name: 'refactor: 代码重构 | A code change that neither fixes a bug nor adds a feature' },
{ value: 'perf', name: 'perf: 性能提升 | A code change that improves performance' },
{ value: 'test', name: 'test: 测试相关 | Adding missing tests or correcting existing tests' },
{ value: 'build', name: 'build: 构建相关 | Changes that affect the build system or external dependencies' },
{ value: 'ci', name: 'ci: 持续集成 | Changes to our CI configuration files and scripts' },
{ value: 'revert', name: 'revert: 回退代码 | Revert to a commit' },
{ value: 'chore', name: 'chore: 其他修改 | Other changes that do not modify src or test files' },
],
useEmoji: false,
emojiAlign: 'center',
useAI: false,
aiNumber: 1,
themeColorCode: '',
scopes: [],
allowCustomScopes: true,
allowEmptyScopes: true,
customScopesAlign: 'bottom',
customScopesAlias: 'custom',
emptyScopesAlias: 'empty',
upperCaseSubject: false,
markBreakingChangeMode: false,
allowBreakingChanges: ['feat', 'fix'],
breaklineNumber: 100,
breaklineChar: '|',
skipQuestions: [],
issuePrefixes: [
// 如果使用 gitee 作为开发管理
{ value: 'link', name: 'link: 链接 ISSUES 进行中' },
{ value: 'closed', name: 'closed: 标记 ISSUES 已完成' }
],
customIssuePrefixAlign: 'top',
emptyIssuePrefixAlias: 'skip',
customIssuePrefixAlias: 'custom',
allowCustomIssuePrefix: true,
allowEmptyIssuePrefix: true,
confirmColorize: true,
scopeOverrides: undefined,
defaultBody: '',
defaultIssues: '',
defaultScope: '',
defaultSubject: ''
}
}
再
pnpm commit
husky
husky是一个钩子工具,但是钩子本身不是husky的,钩子是属于git的
帮助轻松拦截hooks
git hooks提供的pre-commit等,可以在开发的时候,在提交对应的时机,发生一些作用。
package.json:
1.devDependencies:
"husky":"9.0.11"
2.scripts:
"prepare": "husky||true"
package.json:
{
"name": "byelide-demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"lint": "eslint --fix .",
"lint:style": "stylelint **/*.vue",
"spellcheck": "cspell lint --dot --gitignore --color --cache --show-suggestions \"src/**/*.@(html|js|cjs|mjs|ts|tsx|css|scss|md|vue)\"",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"commit": "git-cz",
"prepare": "husky"
},
"config": {
"commitizen": {
"path": "node_modules/cz-git"
}
},
"dependencies": {
"vue": "3.4.26"
},
"devDependencies": {
"@vitejs/plugin-vue": "5.0.4",
"typescript": "5.4.5",
"vite": "5.2.10",
"vue-tsc": "2.0.16",
"eslint": "9.1.1",
"@eslint/js": "9.1.1",
"eslint-plugin-vue": "9.25.0",
"vue-eslint-parser": "9.4.2",
"globals": "15.1.0",
"eslint-plugin-simple-import-sort": "12.1.0",
"stylelint": "16.4.0",
"stylelint-config-recommended-vue": "1.5.0",
"cspell": "8.7.0",
"cz-git": "1.9.1",
"commitizen": "4.3.0",
"husky": "9.0.11"
}
}
pnpm i
npx husky init
pre-commit:预提交 执行提交后会先预提交一下,失败的话全部打回,不会提交
pre-commit:
pnpm lint && pnpm lint:style && pnpm spellcheck &&
npm test
给拦截举个例子
package.json:
scripts:
"commitlint":"commitlint --edit $1"
devDependencies:
"commitlint":"19.3.0"
在.husky/_/commit-msg文件写入:
pnpm commitlint ${1}
pnpm i
git add .
git commit -m “xxxx”
xxxx不允许通过
zx
用JavaScript方式写脚本
以后写脚本的时候可以尝试用zx写
package.json:
1.devDependencies:
"zx":"8.0.2"
2.创建文件pre-commit.mjs 在husky/pre-commit.mjs
里面写zx的配置。可以参考zx官网