博客后臺(tái)管理系統(tǒng)使用后的是基于Vue3+Vite+TS+ESLint+Prettier的開發(fā),具體項(xiàng)目構(gòu)建如下
1、基于Vite創(chuàng)建vue-ts模板的項(xiàng)目骨架
pnpm create vite 項(xiàng)目名稱 --template vue-ts
2、安裝ESLint、Prettier相關(guān)的
ESLint: 控制代碼質(zhì)量
Prettier: 控制代碼風(fēng)格
2.1、安裝ESLint、Prettier相關(guān)相關(guān)包
pnpm install eslint eslint-plugin-vue eslint-config-prettier prettier eslint-plugin-import eslint-plugin-prettier eslint-config-airbnb-base @types/eslint eslint-import-resolver-alias -D
- eslint: ESLint的核心代碼庫(kù)
- prettier: Prettier的格式化代碼的核心代碼庫(kù)
- eslint-config-airbnb-base: airbnb的代碼規(guī)范(依賴plugin-import)
- eslint-config-prettier: eslint結(jié)合prettier的格式化
- eslint-plugin-vue: eslint在Vue里的代碼規(guī)范
- eslint-plugin-import: 項(xiàng)目里面支持eslint
2.2、安裝ESLint、Prettier相關(guān)vscode插件
- ESLint
- Prettier - Code formatter
2.3、配置scripts腳本,初始化ESLint
"lint:create": "eslint --init"
- 執(zhí)行ESLint配置的交互式命令
npm run lint:create
- 配置ESLint過程如下
- 此時(shí)項(xiàng)目根目錄自動(dòng)生成了
.eslintrc.cjs
文件
.eslintrc因?yàn)槭莕ode寫的規(guī)范,所以遵循commonjs規(guī)范,所以是cjs后綴;如果是ESModel規(guī)范,則是mjs后綴。
- 重寫
.eslintrc.cjs
文件
module.exports = {
// 環(huán)境:
env: {
// 瀏覽器
browser: true,
// 最新es語(yǔ)法
es2021: true,
// node環(huán)境
node: true,
},
// 擴(kuò)展的eslint規(guī)范語(yǔ)法,可以被繼承的規(guī)則
// 字符串?dāng)?shù)組:每個(gè)配置繼承它前面的配置
// 分別是:
// eslint-plugin-vue提供的
// eslint-config-airbnb-base提供的
// eslint-config-prettier提供的
// 前綴 eslint-config-, 可省略
extends: ['plugin:vue/vue3-strongly-recommended', 'airbnb-base', 'prettier','./.eslintrc-auto-import.json'],
// eslint 會(huì)對(duì)我們的代碼進(jìn)行檢驗(yàn)
// parser的作用是將我們寫的代碼轉(zhuǎn)換為ESTree(AST)
// ESLint會(huì)對(duì)ESTree進(jìn)行校驗(yàn)
parser: 'vue-eslint-parser',
// 解析器的配置項(xiàng)
parserOptions: {
// es的版本號(hào),或者年份都可以
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
// 源碼類型 默認(rèn)是script,es模塊用module
sourceType: 'module',
// 額外的語(yǔ)言類型
ecmaFeatures: {
tsx: true,
jsx: true,
},
},
// 全局自定義的宏,這樣在源文件中使用全局變量就不會(huì)報(bào)錯(cuò)或者警告
globals: {
defineProps: 'readonly',
defineEmits: 'readonly',
defineExpose: 'readonly',
withDefault: 'readonly',
},
// 插件
// 前綴 eslint-plugin-, 可省略
// vue官方提供了一個(gè)ESLint插件 eslint-plugin-vue,它提供了parser和rules
// parser為 vue-eslint-parser,放在上面的parser字段,rules放在extends字段里,選擇合適的規(guī)則
plugins: ['vue', '@typescript-eslint', 'unused-imports'],
settings: {
// 設(shè)置項(xiàng)目?jī)?nèi)的別名
'import/resolver': {
alias: {
map: [['@', './src'],['/assets', './src/assets']],
extensions: ['.ts', '.js', 'tsx', 'jsx'] // 解決:Unable to resolve path to module
},
// "node": {
// "extensions": [".js", ".jsx", ".ts", ".tsx"]
// }
},
// 允許的擴(kuò)展名
'import/extensions': ['.js', '.jsx', '.ts', '.tsx', '.mjs'],
},
// 自定義規(guī)則,覆蓋上面extends繼承的第三方庫(kù)的規(guī)則,根據(jù)組內(nèi)成員靈活定義
rules: {
'no-console': 0, // 項(xiàng)目中可以使用console.log()
'vue/valid-template-root': 0,
'import/no-extraneous-dependencies': 0, // 解決vite.config.ts的引入報(bào)錯(cuò)
'vue/multi-word-component-names': 0,
'vue/attribute-hyphenation': 0,
'vue/v-on-event-hyphenation': 0,
// 'eslint-plugin-unused-vars': 0,
"no-unused-vars": "off", // or "@typescript-eslint/no-unused-vars": "off",
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{ "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" }
],
"func-names": 0, // 關(guān)閉匿名函數(shù)的校驗(yàn)
"import/extensions": 0, // import時(shí)省略后綴名
"vue/no-mutating-props": 0, // 關(guān)閉子組件改變props時(shí)的報(bào)錯(cuò) baseForm
'no-undef': 0, // 解決按需導(dǎo)入ElMessage 未定義的問題
// already declared in the upper scope
"no-shadow": 0,
},
};
- 添加script腳本命令
"lint": "eslint \"src/**/*.{js,vue,ts}\" --fix"
- 校驗(yàn)ESLint是否配置成功
會(huì)出現(xiàn)紅色線警告
執(zhí)行npm run lint
此時(shí)證明ESLint已經(jīng)配置成功
- 基于vite安裝eslint支持插件
pnpm install vite-plugin-eslint -D
在vite.config.ts中使用
import eslintPlugin from 'vite-plugin-eslint'
plugins: [eslintPlugin()]
- ESLint和Prettier結(jié)合使用
需要新建一下三個(gè)根文件:
.eslintrcignore
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.history
/bin
.eslintrc.js
prettier.config.js
/src/mock/*
vite.config.ts
public/
assets/
build/
vite/
*.html
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
.DS_Store
dist-ssr
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode
!.vscode/extensions.json
.idea
*.suo
*.njsproj
*.sln
*.sw?
components.d.ts
.prettierrc.cjs
module.exports = {
// 一行最多多少字符
printWidth: 80,
// 使用2個(gè)空格縮進(jìn)
tabWidth: 2,
// 使用tab縮進(jìn),不使用空格
useTabs: true,
// 行尾需要分號(hào)
semi: true,
// 使用單引號(hào)
singleQuote: true,
// 對(duì)象的key僅在必要時(shí)使用引號(hào)
quoteProps: "as-needed",
// jsx不使用單引號(hào),而使用雙引號(hào)
jsxSingleQuote: false,
// 尾隨逗號(hào)
trailingComma: "es5",
// 大括號(hào)內(nèi)的收尾需要空格
bracketSpacing: true,
// 箭頭函數(shù),只有一個(gè)參數(shù)的時(shí)候,也需要括號(hào)
arrowParens: "always",
// 每個(gè)文件格式化的范圍是文件的全部?jī)?nèi)容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要寫文件開頭的@prettier
requirePragma: false,
// 不需要自動(dòng)在文件開頭插入@prettier
insertPragma: false,
// 使用默認(rèn)的折行標(biāo)準(zhǔn)
proseWrap: "always",
// 根據(jù)顯示樣式?jīng)Q定html要不要折行
htmlWhitespaceSensitivity: "css",
// 換行符使用lf
endOfLine: "lf",
}
.prettierignore
*
!src/**/
!**/*.js
!**/*.jsx
!**/*.css
!**/*.scss
!**/*.html
!**/*.vue
!**/*.md
!**/*.ts
!**/*.tsx
# some souces directories
src/assets
/dist/*
.local
.husky
.history
.output.js
/node_modules/**
src/.DS_Store
**/*.svg
**/*.sh
/public/*
components.d.ts
#
CHANGELOG.md
vue.config.js
babel.config.js
commitlint.config.js
vite.config.js
.eslintrc.js
- 使用命令格式化代碼【手動(dòng)執(zhí)行命令將eslint和prettier結(jié)合】
npm run prettier-format
"prettier-format": "prettier --config .prettierrc.cjs \"src/**/*.{vue,js,ts}\" --write",
注意: 如果prettier無效,比如自動(dòng)保存無效,則需要重新安裝相關(guān)依賴,如
yarn add prettier@2.8.8 eslint-plugin-prettier@4.2.1 eslint-config-prettier@8.8.0 -D
3、安裝項(xiàng)目啟動(dòng)依賴
pnpm install typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-import-resolver-alias @types/eslint @types/node -D
- @typescript-eslint/parser: ESLint的解析器,用于解析typescript,從而檢查和規(guī)范typescript代碼
- @typescript-eslint/eslint-plugin: 這是一個(gè)ESLint插件,包含了各類定義好的檢測(cè)Typescript代碼的規(guī)范
- eslint-import-resolver-alias: import的時(shí)候使用@等別名
4、重寫tsconfig.ts文件
{
"compilerOptions": {
// 指定es的目標(biāo)版本
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
// 決定如何處理模塊
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
// 編譯過程中需要引入的庫(kù)文件的列表
"lib": ["ESNext", "DOM", "DOM.Iterable"],
// 默認(rèn)所有可見的"@types"包會(huì)在編譯過程中被包含進(jìn)來
"types": ["vite/client"],
"skipLibCheck": true,
"noEmit": true,
// 解析非相對(duì)模塊名的基準(zhǔn)目錄
"baseUrl": ".",
// 模塊名到基于baseurl的路徑映射的列表
"paths": {
"@/": ["scr/"],
"*.ts": ["*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
5、關(guān)于Git操作規(guī)范的配置
Husky:為git客戶端增加的hook,在git commit、git push之前自動(dòng)觸發(fā)的函數(shù),禁止用戶提交一些eslint錯(cuò)誤的代碼
lint-staged:處理暫存區(qū)代碼
commitlint: 對(duì)commit提交的注釋進(jìn)行校驗(yàn),比如 feat還是Feat
5.1、安裝相關(guān)依賴
pnpm install lint-staged husky -D
5.2、git初始化項(xiàng)目
git init
5.3、配置script腳本
"prepare": "husky install",
5.4、本地husky鉤子函數(shù)安裝
npm run prepare
**注意:**此時(shí)項(xiàng)目根目錄生成:.husky目錄
5.5、添加git hooks
- pre-commit鉤子; 添加的是lint-staged 對(duì)git暫存區(qū)代碼的格式化操作
終端執(zhí)行:
npx husky add .husky/pre-commit "npx lint-staged"
5.6、在package.json中添加如下腳本命令
// 表示在執(zhí)行g(shù)it commit 的時(shí)候,會(huì)觸發(fā)pre-commit里的npx lint-staged命令,從而觸發(fā)package.json里的lint-staged的命令。從而觸發(fā)npm run lint和npm run prettier-format
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"npm run lint",
"npm run prettier-format"
]
}
5.7、配置commit注釋校驗(yàn)
- 安裝相關(guān)依賴
pnpm install @commitlint/config-conventional @commitlint/cli -D
- 創(chuàng)建commit-msg鉤子
npx husky add .husky/commit-msg "npx --no -- commitlint --edit ${1}"
3. 新建commitlint.config.cjs
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
// 編譯相關(guān)的修改,例如發(fā)布版本,對(duì)項(xiàng)目構(gòu)建或者依賴的改動(dòng)
'build',
// 新功能(feature)
'feat',
// 修復(fù)bug
'fix',
// 更新某功能
'update',
// 重構(gòu)
'refactor',
// 文檔
'docs',
// 構(gòu)建過程或者輔助工具的變動(dòng),如增加依賴庫(kù)等
'chore',
// 不影響代碼運(yùn)行的變動(dòng)
'style',
// 撤銷commit,回滾到上一個(gè)版本
'revert',
// 性能優(yōu)化
'perf',
// 測(cè)試(單元,集成測(cè)試)
'test',
],
],
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 74],
},
};
6、stylelint 樣式的校驗(yàn)
6.1、vscode安裝Stylelint插件
6.2、安裝相關(guān)依賴
pnpm install stylelint stylelint-config-standard -D
6.3、根目錄新建.stylelintrc.cjs
module.exports = {
extends: [
"stylelint-config-standard"
]
}
6.4、查看是否配置成功
npx stylelint "**/*.css"
沒有報(bào)錯(cuò)則配置成功
6.5、對(duì)scss的格式化處理
- 安裝依賴
pnpm install postcss-html stylelint-config-standard-scss stylelint-config-recommended-vue postcss vite-plugin-stylelint -D
- 修改
.stylelintrc.cjs
module.exports = {
extends: [
"stylelint-config-standard-scss",
"stylelint-config-recommended-vue/scss",
]
}
3、腳本配置文章來源:http://www.zghlxwxcb.cn/news/detail-724949.html
"lint:css": "stylelint **/*.{vue,css,sass,scss} --fix"
- package.json 添加
"*.{vue,less,css,scss,sass}": [
"npm run lint:css"
]
git commit 之前 進(jìn)行暫存區(qū)代碼的style校驗(yàn)
4. 新建.stylelintignore
文章來源地址http://www.zghlxwxcb.cn/news/detail-724949.html
/dist/*
/public/*
7、其他配置
7.1、新建.editorconfig
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
7.2、構(gòu)建不同環(huán)境下的打包行為
"build:dev": "vue-tsc --noEmit && vite build --mode development",
"build:pro": "vue-tsc --noEmit && vite build --mode production"
7.3、package.json文件的補(bǔ)充
{
"name": "smartweb-vue3",
"version": "0.0.0",
"description": "A Vue3 Admin Template",
"author": "South Smart",
"engines": {
"node": ">= 16"
},
"scripts": {
"dev": "vite",
"build": "vite build",
"build:dev": "vite build --mode dev",
"preview": "vite preview",
"serve": "vite preview",
"lint": "yarn lint:es && yarn lint:style && vue-tsc --noEmit",
"lint:es": "eslint src/**/*.{js,jsx,ts,tsx,vue} --max-warnings 0 --fix",
"lint:style": "stylelint src/**/*.{css,scss,vue} --fix",
"lint:vue-tsc": "vue-tsc --noEmit",
"deploy": "./deploy.sh",
"deploy:dev": "./deploy-dev.sh",
"format": "prettier --write .",
"prepare": "husky install",
"preinstall": "node ./build/yarn/check-yarn.js",
"postinstall": "patch-package"
},
"dependencies": {
"@element-plus/icons-vue": "^1.1.4",
"@turf/turf": "^6.5.0",
"buffer": "^6.0.3",
"dayjs": "^1.10.8",
"echarts": "^5.3.1",
"echarts-gl": "^2.0.9",
"element-plus": "2.2.x",
"js-base64": "^3.7.5",
"jsencrypt": "^3.2.1",
"lodash-es": "^4.17.21",
"moment": "^2.29.4",
"nprogress": "^0.2.0",
"pdfjs-dist": "^3.0.279",
"proj4": "^2.8.0",
"qs": "^6.11.0",
"sm-crypto": "^0.3.6",
"smart-ui": "^1.0.2-alpha.0",
"smart3d": "^2.5.1",
"smart3d-vue": "1.1.0-beta.3",
"uuid": "^9.0.0",
"vue": "^3.2.35",
"vue-router": "^4.0.15",
"vue-smart-upload": "^3.0.0"
},
"devDependencies": {
"@babel/core": "^7.16.0",
"@commitlint/cli": "^15.0.0",
"@smart/commitlint-config": "^0.1.2",
"@smart/eslint-config-typescript": "^1.1.0",
"@smart/unplugin-vue-resolvers": "^1.0.0",
"@types/babel__core": "^7.1.16",
"@types/ejs": "^3.1.0",
"@types/html-minifier-terser": "^6.1.0",
"@types/lodash": "^4.14.176",
"@types/lodash-es": "*",
"@types/qs": "^6.9.7",
"@types/sm-crypto": "^0.3.0",
"@typescript-eslint/eslint-plugin": "^4.31.1",
"@typescript-eslint/parser": "^4.31.1",
"@vitejs/plugin-vue": "^1.6.1",
"@vitejs/plugin-vue-jsx": "^1.3.8",
"@vue/compiler-sfc": "^3.2.6",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"axios": "^0.24.0",
"eslint": "^7.32.0",
"eslint-define-config": "^1.1.2",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-vue": "^7.17.0",
"husky": "^7.0.4",
"lint-staged": "11.2.6",
"mockjs": "^1.1.0",
"patch-package": "^6.4.7",
"pinia": "^2.0.14",
"postcss": "^8.4.14",
"postcss-html": "^1.4.1",
"prettier": "^2.4.1",
"pretty-quick": "^3.1.2",
"rollup": "^2.74.1",
"rollup-plugin-copy": "^3.4.0",
"rollup-plugin-external-globals": "^0.6.1",
"sass": "^1.44.0",
"stylelint": "^14.8.3",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recess-order": "^3.0.0",
"stylelint-config-recommended-vue": "^1.4.0",
"stylelint-config-standard": "^25.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"typescript": "4.3.2",
"unplugin-vue-components": "^0.22.8",
"vite": "^2.5.4",
"vite-plugin-externals": "^0.3.0",
"vite-plugin-html": "^2.1.1",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-vue-setup-extend": "^0.1.0",
"vue-tsc": "^1.0.3"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": "eslint --fix",
"*.{css,scss,vue}": "stylelint --fix"
},
"browserslist": [
"> 1%",
"not ie 11",
"not op_mini all"
]
當(dāng)前項(xiàng)目的settings.json配置
{
"typescript.tsdk": "node_modules/typescript/lib",
"npm.packageManager": "pnpm",
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/Thumbs.db": true,
".idea": true,
".metadata": true,
".settings": true,
".externalToolBuilders": true,
".project": true,
"launches": true
},
"search.exclude": {
"dist": true,
"coverage": true,
"node_modules": true,
"lib": true
},
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
// vsocode保存自動(dòng)格式化代碼prettier
"prettier.prettierPath": "./node_modules/prettier",
"prettier.requireConfig": true,
// 配置默認(rèn)格式化工具
"editor.defaultFormatter": "esbenp.prettier-vscode",
// 配置自動(dòng)保存
"files.autoSave": "onFocusChange",
// 配置保存自動(dòng)格式化
"editor.formatOnSave": true,
"eslint.probe": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue"
],
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue"
],
"stylelint.validate": ["css", "less", "postcss", "scss", "vue", "sass"],
"files.associations": {
"adc.h": "c"
},
"cSpell.words": [
]
}
到了這里,關(guān)于基于Vue3+Vite+TS+ESLint+Prettier+Husky+lint-staged+commitlint+stylelint的項(xiàng)目構(gòu)建的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!