前言
大家好,我是林三心,
用最通俗易懂的話講最難的知識點
是我的座右銘,
基礎是進階的前提
是我的初心。今天給大家講一講我是怎麽搭建一個
Vue3 + Ts + Vite
的腳手架的吧
vscode外掛程式
Volar
:Vue3的一款語法提示的外掛程式
Prettier-Code formatter
:prettier的格式化外掛程式
Eslint
:eslint的外掛程式
stylelint
:樣式檔格式化外掛程式
JavaScript and TypeScript Nightly
:起用ts最新語法
計畫初始化
使用
Vite
建立計畫的命令,初始化計畫
npm init vite@latest my-vue-app -- --template vue-ts
tsconfig.json配置
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"strictFunctionTypes": false,
"jsx": "preserve",
"baseUrl": ".",
"allowJs": true,
"sourceMap": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"experimentalDecorators": true,
"lib": ["dom", "esnext"],
"types": ["vite/client"],
"typeRoots": ["./node_modules/@types/", "./types"],
"noImplicitAny": false,
"skipLibCheck": true,
"paths": {
"/@/*": ["src/*"],
"/#/*": ["types/*"]
}
},
"include": [
"tests/**/*.ts",
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/**/*.d.ts",
"types/**/*.ts",
"build/**/*.ts",
"build/**/*.d.ts",
"mock/**/*.ts",
"vite.config.ts",
"src/settings/dist/theme.js",
"src/tools.js"
],
"exclude": ["node_modules", "tests/server/**/*.ts", "dist", "**/*.js"]
}
vite.config.ts配置
import { defineConfig } from'vite'
import vue from'@vitejs/plugin-vue'
import { resolve } from'path'
// npm i --save-dev @types/node
functionpathResolve(dir: string) {
return resolve(process.cwd(), '.', dir)
}
exportdefault defineConfig({
plugins: [vue()],
resolve: {
// 路徑別名
alias: [
{
find: /\/@\//,
replacement: pathResolve('src') + '/',
},
{
find: /\/#\//,
replacement: pathResolve('types') + '/',
},
],
},
// 支持使用tsx語法
esbuild: {
jsxFactory: 'h',
jsxFragment: 'Fragment',
jsxInject: 'import { h } from "vue";',
},
})
支持 Less
直接計畫中安裝
less
就行,跟
webpack
區別就是,
Webpack
需要安裝
less、less-loader
,而
Vite
不需要
less-loader
npm i less -D
vscode設定
主要配置一些
Eslint、Prettier、 stylelint
的使用,以及保存自動呼叫外掛程式進行格式化,計畫新建一個
.vscode
資料夾,資料夾裏新建一個
settings.json
// .vscode/settings.json
{
//========================================
//============== 編輯器 ===================
//========================================
// 光標的動畫樣式
"editor.cursorBlinking": "phase",
// 光標是否啟用平滑插入的動畫
"editor.cursorSmoothCaretAnimation": true,
// vscode重新命名檔或移動檔自動更新匯入路徑
"typescript.updateImportsOnFileMove.enabled": "always",
// 自動替換為當前計畫的內建的typescript版本
"typescript.tsdk": "./node_modeles/typescript/lib",
// 一個制表符占的空格數(可能會被覆蓋)
"editor.tabSize": 2,
// 定義一個預設和的格式程式 (prettier)
"editor.defaultFormatter": "esbenp.prettier-vscode",
// 取消差異編輯器忽略前空格和尾隨空格的更改
"diffEditor.ignoreTrimWhitespace": false,
// 定義函式參數括弧前的處理方式
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
// 在鍵入的時候是否啟動快速建議
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
//========================================
//============== Other ===================
//========================================
// 啟用導航路徑
"breadcrumbs.enabled": true,
//========================================
//============== Other ===================
//========================================
// 按下Tab鍵展開縮寫 (例如Html的div,在鍵入的時候按Tab,快捷生成出來)
"emmet.triggerExpansionOnTab": true,
// 建議是否縮寫 (如Html的<div />)
"emmet.showAbbreviationSuggestions": true,
// 建議是否展開 (如Html的 <div></div>)
"emmet.showExpandedAbbreviation": "always",
// 為制定語法檔定義當前的語法規則
"emmet.syntaxProfiles": {
"vue-html": "html",
"vue": "html",
"xml": {
"arrt_quotes": "single"
}
},
// 在不受支持的語言中添加規則對映
"emmet.includeLanguages": {
"jsx-sublime-babel-tags": "javascriptreact"
},
//========================================
//============== Files ==================
//========================================
// 刪除行位空格
"files.trimTrailingWhitespace": true,
// 末尾插入一個新的空格
"files.insertFinalNewline": true,
// 刪除新行後面的所有新行
"files.trimFinalNewlines": true,
// 預設行尾的字元
"files.eol": "\n",
// 在尋找搜尋的時候整合的檔
"search.exclude": {
"**/node_modules": true,
"**/*.log": true,
"**/*.log*": true,
"**/bower_components": true,
"**/dist": true,
"**/elehukouben": true,
"**/.git": true,
"**/.gitignore": true,
"**/.svn": true,
"**/.DS_Store": true,
"**/.idea": true,
"**/.vscode": false,
"**/yarn.lock": true,
"**/tmp": true,
"out": true,
"dist": true,
"node_modules": true,
"CHANGELOG.md": true,
"examples": true,
"res": true,
"screenshots": true
},
// 搜尋資料夾時候排外的資料夾
"files.exclude": {
"**/bower_components": true,
"**/.idea": true,
"**/tmp": true,
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/node_modules": false
},
// 檔監視器排外的檔 可減少初始化開啟計畫的占用大量cpu
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/.vscode/**": true,
"**/node_modules/**": true,
"**/tmp/**": true,
"**/bower_components/**": true,
"**/dist/**": true,
"**/yarn.lock": true
},
" stylelint.enable": true,
" stylelint.packageManager": "yarn",
//========================================
//============== Eslint ==================
//========================================
// 狀態列顯示Eslint的開啟狀態
"eslint.alwaysShowStatus": true,
// Eslint的選項
"eslint.options": {
// 要檢查的檔拓展名陣列
"extensions": [".js", ".jsx", ".ts", ".tsx", ".vue"]
},
// Eslint校驗的
"eslint.validate": [
"javascript",
"typescript",
"reacttypescript",
"reactjavascript",
"html",
"vue"
],
//========================================
//============== Prettier ================
//========================================
// 使用當前計畫的prettier配置檔,如果沒有則使用預設的配置
"prettier.requireConfig": true,
"editor.formatOnSave": true,
// 以下程式使用prettier預設進行格式化
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": " stylelint.vscode- stylelint"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
// 保存檔的時候的配置
"editor.codeActionsOnSave": {
// 使用Eslint格式化程式碼
"source.fixAll.eslint": true,
// 使用 stylelint格式化程式碼
"source.fixAll. stylelint": true
},
"[vue]": {
"editor.codeActionsOnSave": {
// 使用Eslint格式化程式碼
"source.fixAll.eslint": true,
// 使用 stylelint格式化程式碼
"source.fixAll. stylelint": true
},
"editor.defaultFormatter": "johnsoncodehk.volar"
},
"compile-hero.disable-compile-files-on-did-save-code": true,
"i18n-ally.localesPaths": ["src/locales", "src/locales/lang"]
}
Eslint
Eslint承擔的更多的是程式碼品質上的一個嚴格規範,這萊恩裝的包比較多
npm i
eslint eslint-define-config
eslint-plugin-import
eslint-plugin-node
eslint-plugin-promise
eslint-plugin-vue
vue-eslint-parser
@typescript-eslint/parser
@typescript-eslint/eslint-plugin
eslint-config-prettier
eslint-plugin-jest
-D
計畫中新建兩個檔:
.eslintrc.js
:eslint配置檔
.eslintignore
:eslint規範忽略配置
.eslintrc.js
// .eslintrc.js
// @ts-check
const {
defineConfig
} = require('eslint-define-config')
module.exports = defineConfig({
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',
// 'prettier',
'plugin:prettier/recommended',
'plugin:jest/recommended'
],
rules: {
'vue/script-setup-uses-vars': 'error',
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@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',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/ban-types': 'off',
'@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',
'vue/require-default-prop': 'off',
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'never',
component: 'always'
},
svg: 'always',
math: 'always'
}
]
}
})
.eslintignore
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
Prettier
Prettier
更多的是對於程式碼格式的規範,先安裝外掛程式
npm i prettier -D
然後新建一個
.prettierrc.js
// .prettierrc.js
module.exports = {
printWidth: 100,
tabWidth: 2,
useTabs: false,
semi: false,
vueIndentScriptAnd style: true,
singleQuote: true,
quoteProps: 'as-needed',
bracketSpacing: true,
trailingComma: 'all',
jsxSingleQuote: false,
arrowParens: 'always',
insertPragma: false,
requirePragma: false,
proseWrap: 'never',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'auto',
};
stylelint
stylelint
負責對樣式的格式化規範,先安裝外掛程式
npm i
stylelint
stylelint-config-prettier
stylelint-config-standard
stylelint-order
-D
然後新建一個
stylelint.config.js
// stylelint.config.js
module.exports = {
root: true,
plugins: [' stylelint-order'],
extends: [' stylelint-config-standard', ' stylelint-config-prettier'],
rules: {
'selector-pseudo- class-no-unknown': [
true,
{
ignorePseudo classes: ['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,
'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',
},
],
// 按照指定順序排列
'order/properties-order': [
'position',
'content',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'float',
'width',
'height',
'',
'max-height',
'min-width',
'min-height',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'margin-collapse',
'margin-top-collapse',
'margin-right-collapse',
'margin-bottom-collapse',
'margin-left-collapse',
'overflow',
'overflow-x',
'overflow-y',
'clip',
'clear',
'font',
'font-family',
'font-size',
'font-smoothing',
'osx-font-smoothing',
'font- style',
'font-weight',
'hyphens',
'src',
'line-height',
'letter-spacing',
'word-spacing',
'color',
'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',
'cursor',
'background',
'background-attachment',
'background-color',
'background-image',
'background-position',
'background-repeat',
'background-size',
'border',
'border-collapse',
'border-top',
'border-right',
'border-bottom',
'border-left',
'border-color',
'border-image',
'border-top-color',
'border-right-color',
'border-bottom-color',
'border-left-color',
'border-spacing',
'border- style',
'border-top- style',
'border-right- style',
'border-bottom- style',
'border-left- style',
'border-width',
'border-top-width',
'border-right-width',
'border-bottom-width',
'border-left-width',
'border-radius',
'border-top-right-radius',
'border-bottom-right-radius',
'border-bottom-left-radius',
'border-top-left-radius',
'border-radius-topright',
'border-radius-bottomright',
'border-radius-bottomleft',
'border-radius-topleft',
'quotes',
'outline',
'outline-offset',
'opacity',
'filter',
'visibility',
'size',
'zoom',
'transform',
'box-align',
'box-flex',
'box-orient',
'box-pack',
'box-shadow',
'box-sizing',
'table-layout',
'animation',
'animation-delay',
'animation-duration',
'animation-iteration-count',
'animation-name',
'animation-play-state',
'animation-timing-function',
'animation-fill-mode',
'transition',
'transition-delay',
'transition-duration',
'transition-property',
'transition-timing-function',
'background-clip',
'backface-visibility',
'resize',
'appearance',
'user-select',
'interpolation-mode',
'direction',
'marks',
'page',
'set-link-source',
'unicode-bidi',
'speak',
],
},
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts'],
}
環境變量檔
建立相應檔,可以讓計畫使用環境變量:
.env
.env.develoment
.env.production
全域types
建立
types
資料夾,存放全域相關的
typescript
src資料夾
在
src
資料夾中建立以下資料夾(當然這個看你自己喜好命名,這裏只是我自己的習慣)
api
:存放http請求的介面
assets
:存放一些靜態資源,如
icon、圖片
components
:存放通用元件
design
:存放全域樣式檔
enums
:存放全域的ts字典
hooks
:存放封裝的自訂hook
layouts
:存放布局方案
locales
:存放國際化的語言資料
router
:存放路由相關
settings
:存放一些全域的設定
store
:存放狀態管理相關
utils
:存放通用的工具類函式
views
:存放計畫的頁面
router和pinia
npm i vue-router pinia -D
vue-router
:路由
pinia
:狀態管理(代替vuex)
husky
husky
是
git
送出程式碼的檢查,包括
程式碼是否合格、樣式是否合格、commit資訊是否合格
等檢測
外掛程式
npm i pretty-quick husky @commitlint/cli @commitlint/config-conventional -D
package.json
"install:husky": "husky install",
"lint:pretty": "pretty-quick --staged",
"lint: stylelint": " stylelint --fix \"**/*.{tsx,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/ stylelint/",
"lint:all": "npm run lint:eslint && npm run lint: stylelint"
husky install
在終端裏輸入命令
husky install
,計畫會生成
.husky
資料夾:
.husky
_
.gitignore
husky.sh
完善husky
在
.husky
資料夾中建立三個檔
commit-msg、common.sh、pre-commit
.husky
_
.gitignore
husky.sh
commit-msg
common.sh
pre-commit
commit-msg
// .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
common.sh
// .husky/common.sh
command_exists () {
command -v "$1" >/dev/null2>&1
}
if command_exists winpty && test -t 1; then
exec < /dev/tty
fi
pre-commit
// .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"
[ -n "$CI" ] && exit 0
yarn run lint:pretty
commitlint.config.js
用來規範
git commit -m 'msg'
的
msg
// commitlint.config.js
module.exports = {
// ↓忽略包含init的送出訊息
ignores: [(commit) => commit.includes('init')],
// ↓按照傳統訊息格式來驗證
extends: ['@commitlint/config-conventional'],
// 自訂解析器
parserPreset: {
// 解析器配置
parserOpts: {
// commit 送出頭的規則限制
headerPattern: /^(\w*|[\u4e00-\u9fa5]*)(?:[\(\(](.*)[\)\)])?[\:\:] (.*)/,
// 匹配分組
headerCorrespondence: ['type', 'scope', 'subject'],
// 參照
referenceActions: [
'close',
'closes',
'closed',
'fix',
'fixes',
'fixed',
'resolve',
'resolves',
'resolved',
],
// 對應issue要攜帶#符號
issuePrefixes: ['#'],
// 不相容變更
noteKeywords: ['BREAKING CHANGE'],
fieldPattern: /^-(.*?)-$/,
revertPattern: /^Revert\s"([\s\S]*)"\s*This reverts commit (\w*)\./,
revertCorrespondence: ['header', 'hash'],
warn() {},
mergePattern: null,
mergeCorrespondence: null,
},
},
// ↓自訂送出訊息規則
rules: {
// ↓body以空白行開頭
'body-leading-blank': [2, 'always'],
// ↓footer以空白行開頭
'footer-leading-blank': [1, 'always'],
// ↓header的最大長度
'header-max-length': [2, 'always', 108],
// ↓subject為空
'subject-empty': [2, 'never'],
// ↓type為空
'type-empty': [2, 'never'],
// ↓type的型別
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
' style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
'update',
],
],
},
}
結語
我是林三心,一個熱心的前端菜鳥程式設計師。如果你上進,喜歡前端,想學習前端,那咱們可以交朋友,一起摸魚哈哈,摸魚群,點這個 --> 摸魚沸點 [1]
參考計畫
vue-vben-admin
compass-plan-admin