Vite系列(二):我基于Vite搞了一個項目模板

因卓誒-原文鏈接

vue3-vite2-ts-template

托管地址: github-vue3-vite2-ts-template

  • [x] 使用最新版本的 vite 和 vue3
  • [x] antdv 真正意義上的按需加載組件以及組件css
  • [x] git 提交前的 lint-stage+husky 校驗和美化代碼(prettier), 多人協作風格統一
  • [x] 開發預設 eslint 校驗和自動修復以及 Editorconfig
  • [x] 自帶開發常用依賴,antdv, axios, day, querystring...
  • [x] 適合中小項目的 typescipt 的 mvc 風格架構
  • [x] 工具方法貫徹 hook 風格,且預裝 vueuse
  • [x] scss 基本工具庫封裝,頁面和頁面無需引入,直接使用預定義的全局變量/函數
  • [x] vite/rollup 打包優化
  • [x] storage,cookie TS版本的模塊化方案
  • [x] 預設 Pinia 狀態管理的模塊化以及類型聲明
  • [x] 預設開發環境的 vite-plugin-mock
  • [x] 預設自動裝載路由 vite-plugin-pages
  • [ ] SSR/CSR 優化
  • [ ] 業務組件/type 類型文檔自動生成,且在啟動開發服務器時,自動打開 doc
  • [ ] 動畫方案
  • [ ] 預裝業務常用的 webcomponents 組件(團隊自己開發組件庫)
  • 命令

    啟動/打包 命令

    技術棧:

  • vue3
  • vueRouter4
  • pinia
  • typescript
  • 命令行

    通過安裝Tool,來可視化地使用模板,因為倉庫中的模板大多數都不會全部用到,你可以通過tool去按需引入它們

    npm i enjoy-project-tool -g

    創建模板

    當然,作為模板的伴生工具,我還會繼續維護并且持續提出新的feature來減輕我們開發負擔

    Tool是使用TS開發的,如果你感興趣可以提pr,這是Tool的倉庫

    類型文檔/組件文檔

    文檔待補充,暫定使用

  • dumi作為組件庫文檔
  • 代碼提交

    舊版本的husky和新版還是有很多不一樣的,所以如果你以前用過husky那么你要在代碼提交這里做更多邏輯的話,可以去看看最新的文檔。

    模板中只攔截了pre_commit這個鉤子,目標就是在pre_commit的時候對代碼進行lint和自動修復以及美化,而且僅要對暫存區的文件lint,所以使用了lint-staged。這個組合太常見了,有需求的開發者可以再這個上層定義一些有趣的功能提pr。

    還有一個需求是校驗git commit message的規范,但是對于小團隊來講,校驗這個規范沒有太大必要,也暫時不會對團隊帶來好處,所以愛鼓搗的可以去鼓搗哈。

    可以推薦團隊成員使用 git-commit-plugin-vscode

    vscode 開發小指南

    推薦使用 Volar 插件進行開發,如果你的 IDE 是 Jetbrains 系列的,那么你可能不太需要這個插件,如果你是 vscode 推薦使用 volar。使用 volar,不僅可以在 vue 開發上和jetbrains 的表現一致,還可以得到更完善 vue3 的支持,甚至非常新/在草案的語法糖都能夠快速享受到。

    下載volar地址

    此模板對于vscode有天然的支持,如果你使用vscode,就能使用模板自帶的vscode配置,比如說保存自動lint&fix&prettier或者其他有意思的功能。

  • 有那么一點智能的代碼模板
  • 模板中自帶了若干個vscode的code-snippets,snippets將會持續更新,它和模板深度貼合,可以幫助你擺脫繁瑣的開發。下面就一一描述幾個snippets的作用:

  • model-init-type
  • 初始化@types/model/api的提示工具,自動聲明命名空間以及導出

  • model-init-api
  • 初始化model下的api類,自動引入與之匹配的type類型聲明文件以及其他可能用到的依賴

  • model-init-cache
  • 初始化model下的cache類,自動引入與之匹配的type類型聲明文件以及其他可能用到的依賴

  • controller-init
  • 初始化控制器類

  • vue-init
  • 初始化vue頁面/組件

    AntdV 開發小指南

    傳統的 antdv 的按需加載,都會使用 babel-plugin-import 這個插件進行按需分析然后自動引入,但是 antdv 中有很多嵌套的父子組件:

    <a-menu>  <a-menu-item></a-menu-item></a-menu>

    由于內部設計原因,無法使用這個插件進行按需導入。最主要的是我們已經使用了vite,本身就帶有按需導入,我們只需要處理他們的css的按需引入即可。所以使用了2個插件:

  • vite-plugin-components
  • vite-plugin-style-import
  • 第一個插件主要幫助我們自動識別模板中用到的組件,實現自動引入,也就是說我們使用antdv這樣的組件庫的時候,不需要全量引入,甚至不需要手動的import就可以自動實現按需引入,如圖:

    而且腳手架內置了按需引入css的邏輯,所以antdv本身的設計原因導致引入css問題開發者也不需要擔心。第二個插件主要是輔助第一個插件做按需引入css邏輯的。第一個插件做的按需引入css有些許問題,比如說antdv里面有很多api調用的組件,比如message,通過message方法調用一個組件,這個時候css不生效,就需要使用第二個插件進行處理。

    對于message這樣的api組件的css不生效的原因很簡單,第一個插件僅僅是解析template用到的組件然后自動引入css,但是無法處理import進來的api組件,所以需要第二個插件做處理。

    開發指南

    這一塊根據自身團隊成員的習慣會逐步調整,所以這里的介紹會經常更改。

    這套微不足道的架構足以應對中小APP,也是非常簡單的,主要就是mvc+ts風格。如果你閱讀完整個模板文檔之后,你會發現很多東西都做了模塊化,把業務劃分開了,這也是目前團隊開發沒有注意到的一點,自身開發完爽是爽了,另外一個人維護就要慘了。各種配置,api都找不到,組件/組件參數也找不到,可能為了快速開發,都會去復制老項目和其他頁面的代碼;這雖然也是一種“復用”,但是總歸來說并不是標準的。所以只有將業務劃分開,才能快速定位具體核心代碼,才能快速復用。

    類型

    src/@types

    像大部分工程一樣,把能抽離的type都盡量都抽離到了@types這一層,這一層也暫時根據需求劃分了以下幾個內容:

  • controller
  • model
  • hook
  • store
  • 里面最重度使用的應該是model,我們在model模型中根據業務定義了很多ts,比如user.ts:

    namespace TUserApiModel {  type ReqLogin = {    captcha: string;    password: string;    username: string;    uuid: string;  };  type ResLogin = Promise<    ActionResult<{      token: string;    }>  >;}export default TUserApiModel;

    這兩個就代表了model里面api層(后面會詳細說明model里面的api),使用Req和Res作為前綴也就是請求和響應的類型,那么我們定義好之后,在整個工程中我就可以這樣使用類型:

    那么同理,types文件夾中像store,hook這樣的,也是根據業務劃分,去定義類型的,這里就不再過多闡述了。

    模型

    src/model

    目前model分為2個含義:

  • api
  • cache
  • 前端大部分的數據來源都包含到了,api模型定義了不同業務的api方法,比如user.ts:

    import useRequest from '../../hook/useRequest';export default class UserApiModel {  async login(params: TUserModel.ReqLogin): TUserModel.ResLogin {    return await useRequest({      url: `${params}`,      method: 'get',      options: {        authApi: true      }    });  }}

    useRequest是我們自定義實現的hook函數,我們通過這個hook可以發起請求,那么你可以看到在這個類中定義了login這個方法,入參類型就是TUserModel.ReqLogin, 返回類型就是TUserModel.ResLogin,這個類型都是我們在@types定義的。

    再比如說我們搭配kurimudb做了緩存的模塊化,最常用的緩存插件也預裝好了,我們可以在model里面去寫這樣一段代碼:

    /model/cache/user.ts

    import { Models } from 'kurimudb';import { LocalStorageDriver } from 'kurimudb-driver-localstorage';import { CookieDriver } from 'kurimudb-driver-cookie';export class UserLocalStorage extends Models.keyValue {  constructor() {    super({      name: 'user',      driver: LocalStorageDriver    });  }}export class UserCookie extends Models.keyValue {  constructor() {    super({      name: 'user',      driver: CookieDriver    });  }}

    我們在這里定義了2個kurimudb類,一個是localstorage一個是cookie,我們可以在這里新增一些方法或者直接導出給controller用,因為即便你不新增方法也可以使用kurimudb內置的函數。

    我們擁有kurimudb這樣的庫可以解決存儲模塊化的問題,我們不用關心這個緩存的key是否被使用過,只需要設置好唯一的name值,它就能給我們提供一組方便調用的api。另外kurimudb還有sessionstorage和indexDB的插件,如果業務需要可以快速的安裝,然后聲明一個新的類導出即可使用。

    控制器

    src/controller

    在模板默認自帶了一個user.ts例子,我們在上一個model中說明了apiModel和cacheModel,這里的controller就直接引入它們。并且在controller暴露入口。

    import UserApiModel from '../model/api/user';import { UserLocalStorage, UserCookie } from '../model/cache/user';export default class UserController {  private localStorageModel: UserLocalStorage;  private cookieModel: UserCookie;  private apiModel: UserApiModel;  constructor() {    this.apiModel = new UserApiModel();    this.localStorageModel = new UserLocalStorage();    this.cookieModel = new UserCookie();  }  async login(req: TUserModel.ReqLogin): TUserModel.ResLogin {    return await this.apiModel.login(req);  }}

    控制器我們還可以對api/cache獲取的數據做處理,比如說,后端返回的數據格式前端不便直接展示,我們應該在controller需要做一層轉譯,比如像這樣:

    transform(): { text: string; value: string }[] {    const data = {      '0': '小明',      '1': '小紅'    };    let _arr = [];    let key: keyof typeof data;    for (key in data) {      _arr.push({        text: data[key],        value: key      });    }    return _arr;  }

    視圖(.vue)

    以vue來舉例,我們如何在視圖優雅的調用controller?并且如何使用@types定義的類型來鞏固我們的組件?

    import TUserApiModel from '../../@types/model/api/user';const login = async (params: TUserModel.ReqLogin) => {  await userController.login(params);};// 調用login函數login({  captcha: "",  password: "",  username: "",  uuid: ""})

    當調用login函數時候,提供了與ReqLogin不符合的數據結構,是會出現報錯的。同理,我們調用cache也是一樣,需要在controller把cache封裝一層暴露給vue即可。

    環境變量

    可以根據業務需要,建立業務相關的 env 環境(模式)。 vite-模式文檔

    以下是根目錄默認提供了 3 個環境文件,對應了本地,測試,生產環境

  • .env
  • .env.dev
  • .env.prod
  • 內容示例: 根據業務需要進行配置

    VITE_APP_API=VITE_APP_SECRET=

    那么同理,如果業務需要額外增加新的自定義環境變量,則需要在 src/vite-env.d.ts 中重新定義類型:

    /// <reference types="vite/client" />interface ImportMetaEnv {  VITE_APP_API: string;  VITE_APP_SECRET: string;  // 新的環境變量的定義寫這里}

    Mock

    使用vite-plugin-mock來做本地開發的mock,模板暫時沒有內置生產環境的mock。

    // vite.config.tsviteMockServe({  localEnabled: true //是否開啟本地的mock功能}),

    定義mock api:

    // /mock/user.tsimport { MockMethod } from 'vite-plugin-mock';export default [  {    url: '/api/get',    method: 'get',    response: (res: any) => {      return {        code: 0,        data: {          name: 'this is mock name'        }      };    }  }] as MockMethod[];

    其他的庫

  • dayjs
  • axios
  • vueuse
  • kurimudb
  • query-string
  • 最后編輯于
    ?著作權歸作者所有,轉載或內容合作請聯系作者
    平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
    • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
      沈念sama閱讀 228,702評論 6 534
    • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
      沈念sama閱讀 98,615評論 3 419
    • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
      開封第一講書人閱讀 176,606評論 0 376
    • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
      開封第一講書人閱讀 63,044評論 1 314
    • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
      茶點故事閱讀 71,826評論 6 410
    • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
      開封第一講書人閱讀 55,227評論 1 324
    • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
      沈念sama閱讀 43,307評論 3 442
    • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
      開封第一講書人閱讀 42,447評論 0 289
    • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
      沈念sama閱讀 48,992評論 1 335
    • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
      茶點故事閱讀 40,807評論 3 355
    • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
      茶點故事閱讀 43,001評論 1 370
    • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
      沈念sama閱讀 38,550評論 5 361
    • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
      茶點故事閱讀 44,243評論 3 347
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
      開封第一講書人閱讀 34,667評論 0 26
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
      開封第一講書人閱讀 35,930評論 1 287
    • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
      沈念sama閱讀 51,709評論 3 393
    • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
      茶點故事閱讀 47,996評論 2 374