Vue3企業(yè)級(jí)項(xiàng)目框架搭建

【vue3企業(yè)級(jí)項(xiàng)目骨架搭建,涉及vite、eslint、prettierrc、husky、commitlint、lint-staged、stylelint】 https://www.bilibili.com/video/BV1BV4y1N7pd/?p=2&share_source=copy_web&vd_source=a3810880225685b6ad071f058f59a0fb

Vue3 項(xiàng)目框架搭建

Vite、eslint、prettier、husky、commitlint、lint-staged、stylelint

node—18.13.0、pnpm—7.23.0

1. 使用Vite腳手架初始化項(xiàng)目

https://cn.vitejs.dev/guide/

pnpm create vite development-app --template vue-ts

選擇vue-ts模板

修改vite.config.ts,修改域名端口,自動(dòng)打開瀏覽器
server: {
    host: 'localhost',
    port: 7070,
    open: true
}

2. 代碼加入eslint校驗(yàn),與prettier自動(dòng)格式化

https://eslint.bootcss.com/

eslint運(yùn)行代碼前就可以發(fā)現(xiàn)一些語法錯(cuò)誤和潛在的 bug,目標(biāo)是保證團(tuán)隊(duì)代碼的一致 性和避免錯(cuò)誤

https://www.prettier.cn/

prettier是代碼格式化工具,用于檢測代碼中的格式問題,比如單行代碼長度,tab 長 度,空格,逗號(hào)表達(dá)式等等

區(qū)別聯(lián)系:eslint偏向于把控項(xiàng)目的代碼質(zhì)量,而prettier更偏向于統(tǒng)一項(xiàng)目的編碼 風(fēng)格。eslint有小部分的代碼格式化功能,一般和prettier結(jié)合使用

pnpm install eslint eslint-plugin-vue eslint-config-prettier prettier eslint-plugin-import eslint-plugin-prettier eslint-config-airbnb-base -D

eslint: ESLint的核心庫
prettier: prettier格式化代碼的核心庫
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
eslint-plugin-prettier      將prettier結(jié)合進(jìn)去eslint的插件

配置script腳本,項(xiàng)目安裝eslint配置
"lint:create": "eslint --init"

執(zhí)行npm run lint:create

會(huì)自動(dòng)創(chuàng)建一個(gè).eslintrc.cjs文件

安裝完成后,后面的啟動(dòng)項(xià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        eslint插件,包含了各類定義好的檢測typescript代碼的規(guī)范
eslint-import-resolver-alias            讓我們可以用import的時(shí)候使用@別名

3. eslintrc文件的修改

因?yàn)?code>eslint是 node 工具,所以文件名是.cjs結(jié)尾(commonjs 規(guī)范)——對(duì)應(yīng) 的.mjs就是 ES Module 規(guī)范

module.exports = {
    // 環(huán)境:
    env: {
        // 瀏覽器
        browser: true,
        // 最新es語法
        es2021: true,
        // node環(huán)境
        node: true,
    },
    // 擴(kuò)展的eslint規(guī)范語法,可以被繼承的規(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'
    ],
    // 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',
        // 額外的語言類型
        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,放在上面的parsr字段,rules放在extends字段里,選擇合適的規(guī)則
    plugins: [
        'vue',
        '@typescript-eslint'
    ],
    settings: {
        // 設(shè)置項(xiàng)目內(nèi)的別名
        'import/reslover': {
            alias: {
                map: [
                    ['@', './src']
                ],
            },
        },
        // 允許的擴(kuò)展名
        'import/extensions': ['.js', '.jsx', '.ts', '.tsx', '.mjs'],
    },
    // 自定義規(guī)則,覆蓋上面extends繼承的第三方庫的規(guī)則,根據(jù)組內(nèi)成員靈活定義
    rules: {
        'import/no-extraneous-dependencies': 0,
        'no-param-reassing': 0,
        'vue/multi-word-commponent-names': 0,
        'vue/attribute-hyphenation': 0,
        'vue/v-on-event-hyphenation': 0,
    },
};

修改 package.json 文件,添加一個(gè)腳本命令 "lint": "eslint "src/*/.{js,vue,ts}" --fix"

4. 修改vite.config.js

pnpm install vite-plugin-eslint -D
vite的一個(gè)插件,讓項(xiàng)目可以方便的得到eslint支持,完成eslint配置后,可以快速的將其集成進(jìn)vite之中,便于在代碼不符合eslint規(guī)范的第一時(shí)間看到提示

import eslintPlugin from 'vite-plugin-eslint'

plugins: [vue(), eslintPlugin()]

5. 修改添加常見配置文件

外部新建文件 .eslintrcignore.prettierrc.cjs.prettierignore

.eslintrcignore文件內(nèi)容:

*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
/bin
.eslintrc.js
prettier.config.js
/src/mock/*

# 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

.prettiercjs.js文件內(nèi)容:

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è)文件格式化的范圍是文件的全部內(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文件內(nèi)容:

/dist/*
.local
.output.js
/node_modules/**
src/.DS_Store

**/*.svg
**/*.sh

/public/*
components.d.ts

修改 package.json 文件,添加一個(gè)腳本命令 "prettier-format": "prettier --config .prettierrc.cjs "src/*/.{vue,js,ts}" --write"

tsconfig.json

ts編譯項(xiàng)目的根目錄

Vite使用esbuild將Typescript轉(zhuǎn)譯到JavaScript,但不執(zhí)行任何類型檢查;vue-tsc比tsc速度更快

{
    "compilerOptions": {
        // 指定es的目標(biāo)版本
        "target": "ESNext",
        "useDefineForClassFields": true,
        "module": "ESNext",
        // 決定如何處理模塊
        "moduleResolution": "node",
        "strict": true,
        "jsx": "preserve",
        "sourceMap": true,
        "resolveJsonModule": true,
        "isolatedModules": true,
        "esModuleInterop": true,
        // 編譯過程中需要引入的庫文件的列表
        "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" }]
}

6. Huskylint-stagedcommitlint功能添加

husky是一個(gè)未 git 客戶端增加 hook 的工具,在一些 git 操作之前自動(dòng)觸發(fā)的函數(shù)

https://typicode.github.io/husky/#/

如果我們希望在檢測錯(cuò)誤的同時(shí),自動(dòng)修復(fù)eslint語法錯(cuò)誤,就可以通過后面鉤子實(shí)現(xiàn)

lint-staged過濾出 git 代碼暫存區(qū)(被 git add 的文件)的工具,將所有暫存文件 的列表傳遞給任務(wù)

commitlint是對(duì)我們 git commit 提交的注釋進(jìn)行校驗(yàn)的工具

pnpm install husky -D

配置package.json文件
(新項(xiàng)目需要先 git init 一下)
"prepare": "husky install"

執(zhí)行 npm run prepare, 將husky安裝完畢

----------

后面就可以添加各種 git hooks 鉤子
pre-commit 一般添加的是lint-staged,去對(duì)git暫存區(qū)的代碼做一些格式化的操作
npx husky add .husky/pre-commit "npx lint-staged"

add: 追加
set: 直接覆蓋

----------

lint-staged對(duì)add之后,暫存區(qū)里面的文件進(jìn)行格式化修復(fù)等工作
pnpm install lint-staged -D

package.json文件中,添加

"lint-staged": {
    "*.{js,jsx,vue,ts,tsx}": [
      "npm run lint",
      "npm run prettier-format"
    ]
  }

----------

pnpm install @commitlint/config-conventional @commitlint/cli -D
安裝這兩個(gè)庫,然后新建一個(gè)config文件(commitlint.config.cjs)

添加到git鉤子里
npx husky add .husky/commit-msg "npx --no -- commitlint --edit ${1}"
通過一個(gè)命令添加鉤子

使用git commit -m "提交說明",進(jìn)行提交,提交說明應(yīng)盡量清晰明了,說明本次提交的目的
推薦使用Angular規(guī)范,這是目前使用最廣的寫法

commitlint-config.cjs文件內(nèi)容:

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),如增加依賴庫等
                'chore',
                // 不影響代碼運(yùn)行的變動(dòng)
                'style',
                // 撤銷commit,回滾到上一個(gè)版本
                'revert',
                // 性能優(yōu)化
                'perf',
                // 測試(單元,集成測試)
                '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],
    },
};

常用的 git hooks

  • pre-commit:由 git commit 調(diào)用,在 commit 之前執(zhí)行
  • commit-msg:由 git commit 或 git merge 調(diào)用
  • pre-merge-commit:由 git merge 調(diào)用,在 merge 之前執(zhí)行
  • pre-push:被 git push 調(diào)用,在 git push 之前執(zhí)行,防止進(jìn)行推送

7. stylelint鉤子

CSS 檢查器(linter),幫助我們規(guī)避 CSS 代碼中的錯(cuò)誤并保持一致的編碼風(fēng)格

https://stylelint.io/user-guide/get-started

stylelint CSS代碼檢查器(linter)

1. 安裝vscode插件,Stylelint
2. 修改settings.json,添加下面代碼
{
    "editor.codeActionsOnSave": {
    "source.fixAll.stylelint": true
  },
    "stylelint.validate": [
        "css",
        "less",
        "scss",
        "vue"
    ],
}
3. 安裝項(xiàng)目需要的校驗(yàn)庫,(常見的規(guī)則包)
pnpm install stylelint stylelint-config-standard -D

4. 根目錄下建立 .stylelintrc.cjs
module.exports = {
    extends: ['stylelint-config-standard'],
};

這是一個(gè)標(biāo)準(zhǔn)樣式庫,也可以自動(dòng)添加一些樣式規(guī)則在stylelintrc.cjs文件里面

5. 執(zhí)行 npx stylelint "**/*.css"
發(fā)現(xiàn)項(xiàng)目里面的style.css全局樣式文件,報(bào)錯(cuò)很多
具體到對(duì)應(yīng)的文件,按ctrl+s就會(huì)執(zhí)行自動(dòng)格式化我們?cè)趕etting.json里面添加的語句(第2步)

6. 增加vue里面的樣式支持(附帶less和scss的支持)
對(duì)less的支持
pnpm install stylelint-less stylelint-config-recommended-less -D

對(duì)scss的支持
pnpm install stylelint-scss stylelint-config-recommended-scss postcss -D

pnpm install postcss-html stylelint-config-standard-scss stylelint-config-recommended-vue postcss -D (對(duì)vue里面樣式的支持,vue的樣式需要依賴前面這個(gè)庫)

Vite也同時(shí)提供了對(duì) .scss .sass .less .styl .stylus 文件的內(nèi)置支持,不需要再安裝特定插件和預(yù)處理器

extends: [
    "stylelint-config-standard",
    "stylelint-config-recommended-less",
    "stylelint-config-recommended-scss",
    "stylelint-config-recommended-vue"
]

scss的extends
extends:[
    "stylelint-config-standard-scss",
    "stylelint-config-recommended-vue/scss"
]

7. package.json文件添加
"lint:css": "stylelint **/*.{vue,css,sass,scss} --fix"

8. 給vite添加插件
pnpm install vite-plugin-stylelint -D

修改vite.config.js文件
import stylelitPlugin from 'vite-plugin-stylelint';

plugins: [... stylelitPlugin()],

9. 添加到lint-staged里面,在暫存區(qū)對(duì)文件進(jìn)行格式化
"lint-staged": {
    "*.{js,jsx,vue,ts,tsx}": [
      "npm run lint",
      "npm run prettier-format"
    ],
    "*.{vue,less,css,scss,sass}": [
      "npm run lint:css"
    ]
  }

10. 添加一個(gè).stylelintignore文件
/dist/*
/public/*

11. .stylelintrc.cjs內(nèi)部的其他配置
module.exports = {
    extends: ['stylelint-config-standard', 'stylelint-config-recommended-vue'],
    overrides: [
        // 若項(xiàng)目中存在scss文件,添加以下配置
        {
            files: ['*.scss', '**/*.scss'],
            customSyntax: 'postcss-scss',
            extends: ['stylelint-config-recommended-scss'],
        },
        // 若項(xiàng)目中存在less文件,添加以下配置
        {
            files: ['*.less', '**/*.less'],
            customSyntax: 'postcss-less',
            extends: ['stylelint-config-recommended-less'],
        },
    ],
};

8. 環(huán)境變量和模式

https://cn.vitejs.dev/guide/env-and-mode.html#modes

開發(fā)環(huán)境 dev

測試使用 預(yù)發(fā)環(huán)境,pre

生產(chǎn)環(huán)境,pro

在package.json文件里面寫上對(duì)應(yīng)的腳本

"build:pre": "vue-tsc --noEmit && vite build --mode staging",
"build:pro": "vue-tsc --noEmit && vite build --mode production"

新建文件
.env
.env.development
.env.staging
.env.production

項(xiàng)目配置的內(nèi)容
文件內(nèi)容 VITE_BASE_URL = 'http://yewu-pre.jd.com/api'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,055評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,346評(píng)論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,889評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評(píng)論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,118評(píng)論 0 286
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,637評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,558評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,739評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評(píng)論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,980評(píng)論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評(píng)論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,347評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,702評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容